Backbone.js and Collections: Structure
By on September 10, 2013
Earlier this summer, we launched Collections, the first WordPress theme that we know of that leverages Backbone.js to add single page application (SPA) experiences (e.g., load new content without a full page refresh) in the theme. Now that the theme is in the wild, I would like to share some of our experiences building the theme through a series of posts about Collections. These posts will specifically emphasize the integration of Backbone.js into the theme.
At the outset, we decided that the SPA features would follow the progressive enhancement philosophy. First and foremost, we wanted to build a solid WordPress theme. Then, we wanted to make it special by adding SPA features on top of it (e.g., fast page loading, transition animations). Fortunately, this approach paid off as we were able to create a WordPress theme that did not need to compromise WordPress standards in order to implement SPA features.
A bridge between two worlds
Collections is structured similar to any standards compliant WordPress theme; it contains CSS files, template files and PHP files that implement additional functionality. It works as a normal theme if the files that implement the SPA are removed.
The SPA features are established via three PHP files and nine Javascript files (which are concatenated and minified into a single file for the release builds). One of these files provides routing for a JSON endpoint. If a request for a page has the cspa-json
query variable appended to it, it will cause the content to be rendered via a template file that provides a JSON representation of a post or archive. This second PHP file renders all of the post’s data in a JSON object. The final PHP file handles enqueueing JS files, manages JS template files, and provides extra support for JS functions.
Collectively, these three PHP files provide the bridge between the server side WordPress application and the client side SPA. These files expose the server side components of WordPress that are needed on the client side.
Templating for PHP and JS
In addition to adding these PHP files, template files are modified to work both as a WordPress template and an Underscore.js template.
Page views that are loaded without a full page refresh require Underscore.js templates. Since these templates use HTML identical to the PHP version of the template, we aimed to avoid duplicating the templates; instead, we utilized the same template for multiple purposes. For instance, the following code shows a common expression in a WordPress template to display a post’s content:
<div class="standard-content">
<?php the_content(); ?>
</div>
In order to integrate the Underscore.js template alongside the WordPress template, we modified this code:
<div class="standard-content">
<?php if ( collections_is_js_template() ) : ?>
{{{ content }}}
<?php else : ?>
<?php the_content(); ?>
<?php endif; ?>
</div>
If the template is rendered as a WordPress template, the the_content()
function will render the current post’s content. If the template is rendered as a Underscore.js template (i.e., collections_is_js_template()
returns true
), the template will be written with the {{{ content }}}
placeholder. When the theme loads this template via JS, the {{{ content }}}
placeholder will be replaced by the actual content.
Progress
Other than these changes, the theme operates as a normal WordPress theme. We adhered to the progressive enhancement philosophy with this theme. We built a WordPress theme and then enhanced it by building a SPA on top of it.
In the next part of this series on Collections, I will discuss how this structure, along with the requisite JS files, combine to enable the SPA features in the theme.
Enjoy this post? Read more like it in From the workshop.