50
WORDPRESS AS THE BACKBONE(.JS)

WordPress as the Backbone(.js)

Embed Size (px)

Citation preview

Page 1: WordPress as the Backbone(.js)

WORDPRESS AS THE BACKBONE(.JS)

Page 2: WordPress as the Backbone(.js)

https://github.com/beaulebens/WROPE !

@beaulebens !

#wctoga

Page 3: WordPress as the Backbone(.js)

BEAU LEBENS

AUTOMATTIC

O2

Page 4: WordPress as the Backbone(.js)

WORDPRESS IS FOR BLOGS

Page 5: WordPress as the Backbone(.js)
Page 6: WordPress as the Backbone(.js)

WORDPRESS IS FOR WEBSITES

Page 7: WordPress as the Backbone(.js)
Page 8: WordPress as the Backbone(.js)

WORDPRESS IS A CMS

Page 9: WordPress as the Backbone(.js)
Page 10: WordPress as the Backbone(.js)

WORDPRESS IS A PUBLISHING PLATFORM

Page 11: WordPress as the Backbone(.js)
Page 12: WordPress as the Backbone(.js)

WORDPRESS IS AN APPLICATION BACKEND

Page 13: WordPress as the Backbone(.js)
Page 14: WordPress as the Backbone(.js)
Page 15: WordPress as the Backbone(.js)

WORDPRESS.COM REST APIhttps://developer.wordpress.com/

Page 16: WordPress as the Backbone(.js)

JSON REST APIhttps://wordpress.org/plugins/json-rest-api/

Page 17: WordPress as the Backbone(.js)

JSON

Page 18: WordPress as the Backbone(.js)

JavaScript

Object

Notation

Page 19: WordPress as the Backbone(.js)

REST

Page 20: WordPress as the Backbone(.js)

REpresentational

State

Transfer

Page 21: WordPress as the Backbone(.js)

POST (create)

GET (read)

PUT (update)

DELETE (delete)

Page 22: WordPress as the Backbone(.js)

http://example.com/wp-json/posts/123/comments

Page 23: WordPress as the Backbone(.js)

API

Page 24: WordPress as the Backbone(.js)

Application

Programming

Interface

Page 25: WordPress as the Backbone(.js)

“Programmatic access to your content in a universal format

via simple HTTP requests”

API JSON

REST

Page 26: WordPress as the Backbone(.js)

• Read and Write (when authenticated)

• Perform “all” operations

• Any system that talks HTTP + JSON

Page 27: WordPress as the Backbone(.js)

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

Page 28: WordPress as the Backbone(.js)

WROPEWordPress

River

Of

Posts

Experiment

Page 29: WordPress as the Backbone(.js)
Page 30: WordPress as the Backbone(.js)

JAVASCRIPT?

Page 31: WordPress as the Backbone(.js)
Page 32: WordPress as the Backbone(.js)

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)

Page 33: WordPress as the Backbone(.js)

https://github.com/WP-API/client-js

Page 34: WordPress as the Backbone(.js)

ROUTES

Application state via URIs

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; } }),

Page 35: WordPress as the Backbone(.js)

• 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

Page 36: WordPress as the Backbone(.js)

MODELS

Structured key-value data stores (Post, Comment, etc)

/** * Backbone model for single posts */ wp.api.models.Post = BaseModel.extend( _.extend( /** @lends Post.prototype */ { idAttribute: 'ID',! urlRoot: WP_API_Settings.root + '/posts',! defaults: { ID: null, title: '', status: 'draft', type: 'post', author: new wp.api.models.User(), content: '', link: '', 'parent': 0, date: new Date(), date_gmt: new Date(), modified: new Date(), modified_gmt: new Date(), format: 'standard', slug: '', guid: '', excerpt: '', menu_order: 0, comment_status: 'open', ping_status: 'open', sticky: false, date_tz: 'Etc/UTC', modified_tz: 'Etc/UTC', featured_image: null, terms: {}, post_meta: {}, meta: { links: {} } } }, TimeStampedMixin, HierarchicalMixin ) );

Page 37: WordPress as the Backbone(.js)

• 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

Page 38: WordPress as the Backbone(.js)

COLLECTIONS

List of models (Posts, Comments, etc)

/** * Backbone collection for posts */ wp.api.collections.Posts = BaseCollection.extend( /** @lends Posts.prototype */ { url: WP_API_Settings.root + '/posts',! model: wp.api.models.Post } );

Page 39: WordPress as the Backbone(.js)

• 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

Page 40: WordPress as the Backbone(.js)

VIEWS

Visual representation of models/collections

postView: Backbone.View.extend({ tagName: 'li',! className: 'post',! template: _.template( $('#tpl-post').text() ),! events: { 'click a': 'preventDefault', 'click h1.post-title a': 'goToPage', 'click .featured-image a': 'goToPage' },! initialize: function( options ) { this.render(); },! preventDefault: function( e ) { e.preventDefault(); },! goToPage: function() { WROPE.router.navigate( '/' + this.model.get( 'ID' ), { trigger: true } ); return; },! render: function() { this.$el.html( this.template( this.model.attributes ) ); return this; } }),

Page 41: WordPress as the Backbone(.js)

• 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

Page 42: WordPress as the Backbone(.js)

<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>

SPEAKING OF TEMPLATES

HTML templates, delivered in the DOM as script tags

Page 43: WordPress as the Backbone(.js)

• Built-in ERB-style in Underscore.js

• Token-based replacements (with escaping)

• Basic logic

• Handlebars.js, Mustache.js, etc are also supported

Page 44: WordPress as the Backbone(.js)

SIDELINE

Page 45: WordPress as the Backbone(.js)
Page 46: WordPress as the Backbone(.js)

Routes

Models

Collections

Views/Templates

Page 47: WordPress as the Backbone(.js)

One more thing…

Page 48: WordPress as the Backbone(.js)

<?php!// One off hack to allow Cross Origin Resource Sharing from my laptopadd_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)

Page 49: WordPress as the Backbone(.js)

CODE + DEMO

Page 50: WordPress as the Backbone(.js)

https://github.com/beaulebens/WROPE !

Beau Lebens @beaulebens http://dntd.cc/