This document discusses using WordPress as a backend for building mobile and web applications. It introduces WordPress' REST API which allows accessing WordPress content via HTTP requests. It then outlines how to build a simple mobile-first app called WROPE using the WordPress REST API and the JavaScript library Backbone.js, including setting up models, collections, views and routing to retrieve and display WordPress posts.
25. API JSON
“Programmatic access to
your content in a universal format
via simple HTTP requests”
REST
26. • Read and Write (when authenticated)
• Perform “all” operations
• Any system that talks HTTP + JSON
27. LET’S BUILD AN APP!
• Mobile first, obvs
• Lightweight/lean (mobile is slow)
• The web is cool, so we’ll use web technologies
• Developer with no WordPress/PHP experience
32. BACKBONE.JS
• Helps write structured and sane client-side web apps
• Relatively unopinionated/non-prescriptive
• Basic building blocks for better web apps
• Packages Underscore.js for great helper utilities
• Bundled with WP core
• Small (6.5kb! But that’s a bit deceptive, as we’ll see)
• Lots of boilerplate (but very customizable)
34. ROUTES
routerObj: Backbone.Router.extend({
root: '/dev/WROPE/', !
routes: {
'': 'index',
‘posts/:post’: 'post'
}, !
index: function() {
// Get a collection of posts from WP and render them once returned
WROPE.fetchPosts( function() { this.renderRiver(); }.bind( this ) );
}, !
renderRiver: function() {
WROPE.postsRiver = new WROPE.postsView( { collection: WROPE.posts } ); !
// Load optimized inline images, and reload them when the page is resized
WROPE.optimizeImageSize();
$(window).on('resize', _.debounce( WROPE.optimizeImageSize, 500 ) );
}, !
post: function( post ) {
if ( null === WROPE.posts ) {
WROPE.fetchPosts( function() { this.renderPost( post ); }.bind( this ) );
} else {
this.renderPost( post );
}
}, !
renderPost: function( post ) {
var thePost = WROPE.posts.get( post );
var postView = new WROPE.postView( { model: thePost, tagName: 'div' } );
$( '#wrope' ).slideUp( function() {
$(this).html( postView.$el ).slideDown();
WROPE.optimizeImageSize();
});
return;
}
}),
Application state via URIs
35. • Keep track of where you are in your
application
• Allow for history management (Back button!)
• Can use pushState or hash-based URIs
• Fire events on matched routes
• Fire callbacks based on their matched routes
37. • Fire events when something changes
• Keep track of changed values internally
• Backed up by a REST API/endpoint (server
magic!)
• Have functions for converting to/from the
expected model properties
39. • Bubble up model events
• Fire their own events (add, remove, reset)
• Have a ‘comparator’ to dynamically decide sort
order
• Have functions for filtering/retrieving specific
models
• Backed up by a REST API/endpoint
41. • Listen to events (on models/collections) and
update appropriately
• Handles interactions with the View (clicks etc)
• Correspond to a DOM element (even if it’s
not inserted into the page yet)
• Are agnostic to your templating strategy
42. SPEAKING OF TEMPLATES
<script type="text/html" id="tpl-post">
<div class="post-header">
<div class="post-avatar"><img src="<%= author.attributes.avatar %>" width="40" height="40"></div>
<h1 class="post-title"><a href="<%= link %>"><%= title %></a></h1>
<div class="post-author"><%= author.name %></div>
<div class="post-date"><%= date %></div>
</div>
<div class="post-body">
<% if ( featured_image ) { %>
<div class="featured-image">
<a href="<%= link %>">
<img data-src="<%= photon( featured_image.source ) %>" alt="" class="feature">
</a>
</div>
<% } %>
<%= excerpt %>
</div>
</script>
HTML templates, delivered in the DOM as script tags
43. • Built-in ERB-style in Underscore.js
• Token-based replacements (with escaping)
• Basic logic
• Handlebars.js, Mustache.js, etc are also
supported
48. <?php
!
// One off hack to allow Cross Origin Resource Sharing from my laptop
add_action( 'wp_json_server_before_serve', function() {
// Allow my laptop to talk to WordPress
header( 'Access-Control-Allow-Origin: http://beaurrito.local' );
!
// jQuery sends a preflight OPTIONS request to confirm control headers.
// If that's what this request is, then after we've sent the above headers we can bail.
if ( 'OPTIONS' == strtoupper( $_SERVER['REQUEST_METHOD'] ) ) {
exit;
}
});
CORS HACK
On your WP install (mu-plugins)