Retrieving markup from the REST API infrastructure, the JavaScript code.
Quick recap
In my last post I’ve tackled the issue of allowing for the live edit of the post thumbnail within the Front to Back plugin.
The live editing happens in the Theme Customizer and implementing it requires some front end and backend communication.
The template
The Front to Back plugin is meant to be a developer tool.
As such it does not work as a theme builder delegating layout and page components to anyone with administration rights but produces page specific template files in the current theme root folder.
The starting template I’ve used to test the featured image live editing is this one, it’s the ftb-templates/about-us.php
file in the theme root folder
<?php
get_header(); ?>
<div id="primary" class="content-area" xmlns="http://www.w3.org/1999/html">
<main id="main" class="site-main" role="main">
<?php while ( have_posts() ) : the_post(); ?>
<article>
<header class="entry-header">
<h1 class="entry-title">
<ftb-title element=".entry-title">About us</ftb-title>
</h1>
</header><!-- .entry-header -->
<div class="featured-image">
<ftb-featured-image attr="class=thumbnail-id" size="full"></ftb-featured-image>
</div>
</article><!-- #post-## -->
<?php endwhile; ?>
</main><!-- .site-main -->
<?php get_sidebar( 'content-bottom' ); ?>
</div><!-- .content-area -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>
Using the ftb-*
markup tags I’m telling WordPress I want the user to be able to edit the page title and featured image in the Theme Customizer. The generated page template is the page-about-us.php
file, located in the theme root folder, and has the following code:
<?php get_header(); ?><div xmlns="http://www.w3.org/1999/html" id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<?php while ( have_posts() ) : the_post(); ?>
<article>
<header class="entry-header">
<h1 class="entry-title">
<?php the_title(); ?>
</h1>
</header><!-- .entry-header -->
<div class="featured-image">
<?php ftb_the_post_thumbnail( 'full', array( 'class' => 'thumbnail-id' ) ); ?>
</div>
</article><!-- #post-## -->
<?php endwhile; ?>
</main><!-- .site-main -->
<?php get_sidebar( 'content-bottom' ); ?>
</div><!-- .content-area -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>
Not different from many WordPress templates then but for the use of the ftb_the_post_thumbnail
template tag: this will take care of returning either the post thumbnail markup or an empty img
tag should the post thumbnail not be set.
The Theme Customizer editing section looks like this:
Live editing, the JavaScript side
To “live edit” the post thumbnail, or any attachment for the matter, I’m triggering a request to the WordPress backend to obtain the attachment HTML code; the Kirky library control I’m using for the featured image is the image
one and when a user edits the featured image in the Theme Customizer the JavaScript callback will be passed two arguments:
- the jQuery selector identifying the changing element
- the new image
src
or none if the image is removed
I’ve set up the Kirky library to use the FTB.Attachments.replace
JavaScript callback when editing the featured image and here it is in its webpack context
var $ = require( './../globals/jQuery.js' ),
Backbone = require( './../globals/Backbone.js' ),
Events = require( './Events.js' ),
Backend = require( './Backend.js' );
module.exports = Backbone.Model.extend( {
events: Events,
backend: new Backend(),
replace: function ( element, newSrc ) {
var $element = $( element ), size, attr, html, self = this;
$element.each( function () {
$this = $( this );
// tell anything listening we are going to replace an image
self.events.trigger( 'ftb.attachment.replace_src.before', element, newSrc );
// the `ftb_the_post_thumbnail` template tag will add these two data attributes to the markup
size = $this.data( 'ftb-size' );
attr = $this.data( 'ftb-attr' );
// require the new HTML from the backend...
html = self.backend.get_attachment_image_from( newSrc, size, attr ).success( function ( html ) {
// something went wrong, abort
if ( html === false ) {
return;
}
//... and on success replace it
$this.replaceWith( html );
// tell anything listening we have replaced the attachment HTML
self.events.trigger( 'ftb.attachment.replace_src.after', element, newSrc, html );
} );
}
} );
The Backend
object abstracts backend communications for other classes:
var $ = require( './../globals/jQuery.js' ),
Backbone = require( './../globals/Backbone.js' ),
ftbData = require( './../globals/ftbData.js' );
module.exports = Backbone.Model.extend( {
get_attachment_image_from: function ( newSrc, size, attr ) {
var settings = {
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'X-WP-NONCE', ftbData.nonce );
},
url: ftbData.rest_url_prefix + '/ftb/v1/markup/attachment',
data: {
newSrc: newSrc,
size: size,
attr: attr
},
dataType: 'json'
};
// return the promise to allow for client classe to handle it
return $.get( settings );
}
} );
The beforeSend
function sets the X-WP-NONCE
header to a nonce that’s localized in the ftbData
object; such nonce is generated with a wp_create_nonce( 'wp_rest' )
call.
The dataType
is set to json
and not html
due to the fact that the REST API infrastructure will json_encode
anything before it’s returned and setting the dataType
to json
grants the response will be properly decoded upon arrival.
Next
I will dive into the backend side of things to have the featured image live editing fully working.