SlideShare a Scribd company logo
1 of 44
Download to read offline
INTRODUCTION TO 
BACKBONE.JS WITH 
WORDPRESS 
Brian Hogg / @brianhogg
AGENDA 
Why Backbone.js 
Basics of Backbone.js / Underscore.js 
End-to-end example plugin (Github)
WHO ARE YOU?
WHY BACKBONE? 
Enforces some structure on your JavaScript 
Events system
WHY NOT JUST JQUERY? 
Performance 
Leveraging the community 
Re-inventing the wheel 
Code structure (avoid 1000+ lines of jQuery that "just works")
WHAT IS BACKBONE.JS? 
STRUCTURE (MV*) 
Uses jQuery, but only hard requirement is Underscore.js
WHAT IS 
UNDERSCORE.JS? 
UTILITY FUNCTIONS WITH _ 
_.each 
_.template 
Lots more: http://documentcloud.github.io/underscore/
TEMPLATES 
var template = _.template("hello <%= name %>"); 
var html = template({ name: 'Brian' }); 
console.log( html ); // "hello Brian" 
var template = _.template("<strong><%- value %></strong>"); 
var html = template({ value: '<script>' }); 
console.log( html ); // "<strong>&lt;script&gt;</strong>"
ALTERNATIVES 
EMBER.JS, ANGULAR.JS, ... 
Multiple ways of doing similar things. Even in Backbone.JS: 
“It's common for folks just getting started to treat 
the examples listed on this page as some sort of 
gospel truth. In fact, Backbone.js is intended to 
be fairly agnostic about many common patterns 
in client-side code.” 
http://backbonejs.org/#FAQ-tim-toady
BACKBONE / 
UNDERSCORE 
INCLUDED IN WORDPRESS SINCE 3.5 
The "backbone" of the media manager, revisions UI
MODELS 
“Models are the heart of any JavaScript 
application, containing the interactive data as 
well as a large part of the logic surrounding it: 
conversions, validations, computed properties, 
and access control. You extend Backbone.Model 
with your domain-specific methods, and Model 
provides a basic set of functionality for 
managing changes.”
MODEL EXAMPLE 
var Post = Backbone.Model.extend({ 
defaults: { 
title: "", 
post_status: "draft" 
}, 
initialize: function() { 
console.log("creating a post"); 
} 
}); 
var post = new Post({ title: "Hello, world", post_status: "draft" }); 
var title = post.get("title"); // Hello, world 
var post_status = post.get("post_status"); // draft 
All models have an id attribute for syncing up with a server
LISTENING FOR CHANGES 
post.on("change:title", function(model) { 
alert("Title changed to: " + model.get("title")); 
}); 
Or in the models initialize with: 
this.on("change:title", this.titleChanged);
VIEWS 
Used to turn a model into something you can see 
Always contains a DOM element (the el property), whether 
its been added to the viewable page or not
BARE MINIMUM TO USE BACKBONE 
var PostView = Backbone.View.extend({ 
events: { 
"click .edit": "editPost", 
"change .post_status": "statusChanged" 
}, 
editPost: function(event) { 
// ... 
}, 
statusChanged: function(event) { 
// ... 
} 
}); 
var postView = new PostView({ el: '#my-form' });
VIEW EXAMPLE 
var PostView = Backbone.View.extend({ 
tagName: "div", // div by default 
className: "bbpost", // for styling via CSS 
events: { 
"click .edit": "editPost", 
"change .post_status": "statusChanged" 
}, 
initialize: { 
this.listenTo(this.model, "change", this.render); 
}, 
render: { 
// ... 
} 
});
RENDERING THE VIEW 
var template = _.template($("#tmpl-bbpost").html()); 
var html = template(this.model.toJSON()); 
this.$el.html(html); 
return this; // for chaining 
This uses Underscore.js' _.template, but you can use another!
ACCESSING THE DOM ELEMENT 
this.$el 
this.$el.html() 
this.el 
// From within a parent view 
var view = new PostView({ model: post }); 
this.$el.append(view.render().el); 
this.$ 
this.$('.title').val()
COLLECTIONS 
Ordered set of models 
var Posts = Backbone.Collection.extend({ 
model: Post 
}); 
var post1 = new Post({ title: "Hello, world" }); 
var post2 = new Post({ title: "Sample page" }); 
var myPosts = new Posts([ post1, post2 ]);
POPULATING COLLECTIONS FROM THE SERVER 
Out of the box, Backbone.js supports RESTful APIs through 
Backbone.sync(method, model, [options]): 
create → POST /collection 
read → GET /collection[/id] 
update → PUT /collection/id 
patch → PATCH /collection/id 
delete → DELETE /collection/id
What Backbone expects when fetching/reading the collection: 
[ 
{ 
id: 1, 
title: "Hello, world" 
}, 
{ 
... 
} 
] 
What this sends: 
wp_send_json_success( array( 'id': 1, 'title': 'Hello, world' ) ); 
{ 
success: true, 
data: [ 
{ 
id: 1, 
title: "Hello, world" 
} 
] 
}
So, just override .parse() to accommodate: 
var Posts = Backbone.Collection.extend({ 
model: Post, 
url: ajaxurl, // defined for us if we're in /wp-admin 
parse: function( response ) { 
return response.data; 
} 
}); 
// Kick things off 
$(document).ready(function() { 
posts = new Posts(); 
postsView = new PostsView({ collection: posts }); 
posts.fetch({ data: { action: 'bbpost_fetch_posts' } }); 
}); 
Or can override .sync(), or even .fetch()
Note on calling .fetch() on page load: 
“Note that fetch should not be used to populate 
collections on page load — all models needed at 
load time should already be bootstrapped in to 
place. fetch is intended for lazily-loading models 
for interfaces that are not needed immediately: 
for example, documents with collections of notes 
that may be toggled open and closed.” 
http://backbonejs.org/#Collection-fetch 
Depends on the situation
ROUTERS 
Used for routing your application's URLs when using hash tags 
(#)
(CONTRIVED) EXAMPLE 
MANAGING WORDPRESS POST TITLES AND PUBLISH/DRAFT 
STATUS IN AN ADMIN PANEL 
DEMO
DIRECTORY STRUCTURE 
plugins/ 
backbone-js-wp-example/ 
backbone-js-wp-example.php 
css/ 
admin.css 
js/ 
collections/ 
posts.js 
models/ 
post.js 
views/ 
post.js 
posts.js
MODELS/POST.JS 
var bbp = bbp || {}; 
(function($){ 
bbp.Post = Backbone.Model.extend({ 
}); 
})(jQuery); 
Could set defaults here, if creating new posts
BACKBONE-JS-WP-EXAMPLE.PHP 
/* 
Plugin Name: Backbone.js WP Example 
Plugin URI: 
Description: Basic Backbone.js Example in WordPress to edit basic Post properties 
Version: 1.0 
Author: Brian Hogg 
Author URI: http://brianhogg.com 
License: GPL2 
*/ 
define( 'BBPOST_VERSION', 1 );
BACKBONE-JS-WP-EXAMPLE.PHP 
SETTING UP ACTIONS 
class BBPostAdmin { 
public function __construct() { 
if ( is_admin() ) { 
add_action( 'wp_ajax_bbpost_fetch_posts', array( &$this, 'ajax_fetch_posts' ) add_action( 'wp_ajax_bbpost_save_post', array( &$this, 'ajax_save_post' ) ); 
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) { 
add_action( 'admin_menu', array( &$this, 'admin_menu' ) ); 
if ( isset( $_GET['page'] ) and 'bbpostadmin' == $_GET['page'] ) { 
add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_scripts' } 
} 
} 
}
BACKBONE-JS-WP-EXAMPLE.PHP 
ADDING THE MENU 
add_menu_page( 'Backbone JS Post Admin Example', 'Backbone JS Post Admin Example', 'add_users' 
admin_menu() function
BACKBONE-JS-WP-EXAMPLE.PHP 
ADDING THE SCRIPTS 
// Add backbone.js models first, then collections, followed by views 
$folders = array( 'models', 'collections', 'views' ); 
foreach ( $folders as $folder ) { 
foreach ( glob( dirname( __FILE__ ) . "/js/$folder/*.js" ) as $filename ) { 
$basename = basename( $filename ); 
wp_register_script( "$folder/$basename", plugins_url( "js/$folder/$basename", __FILE__ wp_enqueue_script( "$folder/$basename" ); 
} 
} 
wp_register_style( 'bbpost.admin.css', plugins_url( 'css/admin.css', __FILE__ ), false, ECN_wp_enqueue_style( 'bbpost.admin.css' ); 
enqueue_scripts() function 
wp-util gives us the wp.ajax helper function
ADMIN PAGE TEMPLATE 
<script id="tmpl-bbpost" type="text/html"> 
<div class="bbpost"> 
<h2> <%- title %> 
</h2> 
Post title: <input type="text" class="title" value="<%- title %>" />, Status: 
<select class="post_status"> 
<option value=""></option> 
<option value="publish" <% if ( 'publish' == post_status ) { %>SELECTED 
<option value="draft" <% if ( 'draft' == post_status ) { %>SELECTED 
</select> 
<button>Update</button> 
</div> 
</script> 
<h1>Backbone.js WordPress Post Admin Example</h1> 
<div id="bbposts"> 
</div> 
admin_page()
ADMIN PAGE TEMPLATE 
INDIVIDUAL POST 
<div class="bbpost"> 
<!-- will update when the model updates, automatically --> 
<h2> </h2> 
Post title: <input type="text" class="title" value="<%- title %>" />, 
Status: 
<select class="post_status"> 
<option value=""></option> 
<option value="publish" <% if ( 'publish' == post_status ) { %>SELECTED >Published 
<option value="draft" <% if ( 'draft' == post_status ) { %>SELECTED >Draft</ 
</select> 
<button>Update</button> 
</div> 
<%- title %> 
<% } %>
VIEWS/POSTS.JS 
var bbp = bbp || {}; 
(function($){ 
bbp.PostsView = Backbone.View.extend({ 
el: '#bbposts', // Specifying an already existing element 
initialize: function() { 
this.collection.bind('add', this.addOne, this); 
}, 
addOne: function(post) { 
var view = new bbp.PostView({ model: post }); 
this.$el.append(view.render().el); 
} 
}); 
$(document).ready(function() { 
bbp.posts = new bbp.PostsCollection(); 
bbp.postsView = new bbp.PostsView({ collection: bbp.posts }); 
bbp.posts.fetch({ data: { action: 'bbpost_fetch_posts' } }); 
}); 
})(jQuery);
VIEWS/POST.JS 
var bbp = bbp || {}; 
(function($){ 
bbp.PostView = Backbone.View.extend({ 
className: 'bbpost', 
initialize: function() { 
this.model.on("change", this.render, this); 
}, 
render: function() { 
var template = _.template($('#tmpl-bbpost').html()); 
var html = template(this.model.toJSON()); 
this.$el.html(html); 
return this; 
}, 
events: { 
'click button': 'updatePost' 
}, 
updatePost: function() { 
this.model.set('title', this.$('.title').val()); 
this.model.set('post_status', this.$('.post_status').val()); 
this.model.save(); 
} 
}); 
})(jQuery);
BACKBONE-JS-WP-EXAMPLE.PHP 
FUNCTION TO SEND THE POST DATA 
if ( ! current_user_can( 'edit_published_posts' ) ) 
wp_send_json_error(); 
$posts = get_posts( 
array( 
'post_status' => 'any' 
) 
); 
$retval = array(); 
foreach ( $posts as $post ) { 
$retval[] = array( 
'id' => $post->ID, 
'title' => $post->post_title, 
'post_status' => $post->post_status, 
); 
} 
wp_send_json_success( $retval ); 
ajax_fetch_posts()
COLLECTIONS/POSTS.JS 
var bbp = bbp || {}; 
(function($){ 
bbp.PostsCollection = Backbone.Collection.extend({ 
model: bbp.Post, 
url: ajaxurl, 
parse: function ( response ) { 
// This will be undefined if success: false 
return response.data; 
} 
}); 
})(jQuery);
SAVING 
OVERRIDE SAVE() IN MODELS/POST.JS 
var bbp = bbp || {}; 
(function($){ 
bbp.Post = Backbone.Model.extend({ 
save: function( attributes, options ) { 
options = options || {}; 
options.data = _.extend( options.data || {}, { 
action: 'bbpost_save_post', 
data: this.toJSON() 
}); 
var deferred = wp.ajax.send( options ); 
deferred.done( function() { 
alert('done'); 
}); 
deferred.fail( function() { 
alert('failed'); 
}); 
} 
}); 
})(jQuery);
BACKBONE-JS-WP-EXAMPLE.PHP 
SAVING A POST TITLE/STATUS 
if ( ! $post = get_post( (int) $_POST['data']['id'] ) ) 
wp_send_json_error(); 
if ( ! current_user_can( 'edit_post', $post->ID ) ) 
wp_send_json_error(); 
if ( wp_update_post( array( 
'ID' => $post->ID, 
'post_title' => $_POST['data']['title'], 
'post_status' => $_POST['data']['post_status'], 
) ) == $post->ID ) 
wp_send_json_success(); 
else 
wp_send_json_error(); 
ajax_save_post() function
Extra work to set up initially, but worth it later on!
WP-BACKBONE 
Special versions of Backbone.View (wp.Backbone.View) 
revisions.view.Frame = wp.Backbone.View.extend({ 
className: 'revisions', 
template: wp.template('revisions-frame'), 
// ... 
}); 
Handling of SubViews 
templates use <# #> instead of <% %> (as PHP can see <% %> 
as code: see trac 
for details) 
See revisions.js for an example
RESOURCES 
https://github.com/brianhogg/backbone-js-wp-example 
http://backbonejs.org/ 
http://backbonetutorials.com/ 
https://github.com/addyosmani/backbone-fundamentals 
http://kadamwhite.github.io/talks/2014/backbone-wordpress-wpsessions 
WordPress revisions.js
ENJOY! 
brianhogg.com | @brianhogg

More Related Content

What's hot

Django Templates
Django TemplatesDjango Templates
Django TemplatesWilly Liu
 
Ch9 .Best Practices for Class-Based Views
Ch9 .Best Practices  for  Class-Based ViewsCh9 .Best Practices  for  Class-Based Views
Ch9 .Best Practices for Class-Based ViewsWilly Liu
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorialClaude Tech
 
JavaScript in Drupal 7: What developers need to know
JavaScript in Drupal 7: What developers need to knowJavaScript in Drupal 7: What developers need to know
JavaScript in Drupal 7: What developers need to knowkatbailey
 
td_mxc_rubyrails_shin
td_mxc_rubyrails_shintd_mxc_rubyrails_shin
td_mxc_rubyrails_shintutorialsruby
 
Django class based views for beginners
Django class based views for beginnersDjango class based views for beginners
Django class based views for beginnersSpin Lai
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Luka Zakrajšek
 
Phase2 OpenPublish Presentation SF SemWeb Meetup, April 28, 2009
Phase2 OpenPublish Presentation SF SemWeb Meetup, April 28, 2009Phase2 OpenPublish Presentation SF SemWeb Meetup, April 28, 2009
Phase2 OpenPublish Presentation SF SemWeb Meetup, April 28, 2009Krista Thomas
 
Geodaten & Drupal 7
Geodaten & Drupal 7Geodaten & Drupal 7
Geodaten & Drupal 7Michael Milz
 
Viking academy backbone.js
Viking academy  backbone.jsViking academy  backbone.js
Viking academy backbone.jsBert Wijnants
 
Drush - use full power - DrupalCamp Donetsk 2014
Drush - use full power - DrupalCamp Donetsk 2014Drush - use full power - DrupalCamp Donetsk 2014
Drush - use full power - DrupalCamp Donetsk 2014Alex S
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJSAaronius
 
Drupal Development
Drupal DevelopmentDrupal Development
Drupal DevelopmentJeff Eaton
 
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...Atlassian
 
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...Atlassian
 
Mule esb
Mule esbMule esb
Mule esbKhan625
 

What's hot (20)

Django Templates
Django TemplatesDjango Templates
Django Templates
 
Django Bogotá. CBV
Django Bogotá. CBVDjango Bogotá. CBV
Django Bogotá. CBV
 
Ch9 .Best Practices for Class-Based Views
Ch9 .Best Practices  for  Class-Based ViewsCh9 .Best Practices  for  Class-Based Views
Ch9 .Best Practices for Class-Based Views
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorial
 
Alfredo-PUMEX
Alfredo-PUMEXAlfredo-PUMEX
Alfredo-PUMEX
 
JavaScript in Drupal 7: What developers need to know
JavaScript in Drupal 7: What developers need to knowJavaScript in Drupal 7: What developers need to know
JavaScript in Drupal 7: What developers need to know
 
td_mxc_rubyrails_shin
td_mxc_rubyrails_shintd_mxc_rubyrails_shin
td_mxc_rubyrails_shin
 
Django class based views for beginners
Django class based views for beginnersDjango class based views for beginners
Django class based views for beginners
 
RicoLiveGrid
RicoLiveGridRicoLiveGrid
RicoLiveGrid
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
 
Phase2 OpenPublish Presentation SF SemWeb Meetup, April 28, 2009
Phase2 OpenPublish Presentation SF SemWeb Meetup, April 28, 2009Phase2 OpenPublish Presentation SF SemWeb Meetup, April 28, 2009
Phase2 OpenPublish Presentation SF SemWeb Meetup, April 28, 2009
 
Geodaten & Drupal 7
Geodaten & Drupal 7Geodaten & Drupal 7
Geodaten & Drupal 7
 
Viking academy backbone.js
Viking academy  backbone.jsViking academy  backbone.js
Viking academy backbone.js
 
Drush - use full power - DrupalCamp Donetsk 2014
Drush - use full power - DrupalCamp Donetsk 2014Drush - use full power - DrupalCamp Donetsk 2014
Drush - use full power - DrupalCamp Donetsk 2014
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
 
Drupal Development
Drupal DevelopmentDrupal Development
Drupal Development
 
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
No Coding Necessary: Building Confluence User Macros Cheat Sheet - Atlassian ...
 
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
No Coding Necessary: Building User Macros and Dynamic Reports Inside Confluen...
 
Mule esb
Mule esbMule esb
Mule esb
 

Viewers also liked

Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Arc & Codementor
 
Backbone.js
Backbone.jsBackbone.js
Backbone.jstonyskn
 
Kidney Power Point Presentation
Kidney Power Point  PresentationKidney Power Point  Presentation
Kidney Power Point Presentationkingsley ubawike
 
Body parts (Vocabulary Introduction) Lesson 1
Body parts (Vocabulary Introduction) Lesson 1Body parts (Vocabulary Introduction) Lesson 1
Body parts (Vocabulary Introduction) Lesson 1Mike Stonem
 
Parts of body
Parts of bodyParts of body
Parts of bodySUE
 
Kidney anatomy, physiology and disorders
Kidney anatomy, physiology and disordersKidney anatomy, physiology and disorders
Kidney anatomy, physiology and disordersUniversity of Mauritius
 
The human brain presentation
The human brain presentationThe human brain presentation
The human brain presentationSilvia Borba
 

Viewers also liked (10)

Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
Kidney Power Point Presentation
Kidney Power Point  PresentationKidney Power Point  Presentation
Kidney Power Point Presentation
 
Colon cancer
Colon cancer Colon cancer
Colon cancer
 
Liver anatomy
Liver anatomyLiver anatomy
Liver anatomy
 
Body parts (Vocabulary Introduction) Lesson 1
Body parts (Vocabulary Introduction) Lesson 1Body parts (Vocabulary Introduction) Lesson 1
Body parts (Vocabulary Introduction) Lesson 1
 
Parts of body
Parts of bodyParts of body
Parts of body
 
Kidney anatomy, physiology and disorders
Kidney anatomy, physiology and disordersKidney anatomy, physiology and disorders
Kidney anatomy, physiology and disorders
 
Body parts powerpoint
Body parts powerpointBody parts powerpoint
Body parts powerpoint
 
The human brain presentation
The human brain presentationThe human brain presentation
The human brain presentation
 

Similar to Introduction to backbone presentation

WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST APIWordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST APIBrian Hogg
 
WordPress as the Backbone(.js)
WordPress as the Backbone(.js)WordPress as the Backbone(.js)
WordPress as the Backbone(.js)Beau Lebens
 
Djangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django applicationDjangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django applicationMasashi Shibata
 
Gutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesGutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesRiad Benguella
 
Vue routing tutorial getting started with vue router
Vue routing tutorial getting started with vue routerVue routing tutorial getting started with vue router
Vue routing tutorial getting started with vue routerKaty Slemon
 
React.js or why DOM finally makes sense
React.js or why DOM finally makes senseReact.js or why DOM finally makes sense
React.js or why DOM finally makes senseEldar Djafarov
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneRafael Felix da Silva
 
WordPress Structure and Best Practices
WordPress Structure and Best PracticesWordPress Structure and Best Practices
WordPress Structure and Best Practicesmarkparolisi
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAERon Reiter
 
Avinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPressAvinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPresswpnepal
 
Using WordPress as your application stack
Using WordPress as your application stackUsing WordPress as your application stack
Using WordPress as your application stackPaul Bearne
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejsNick Lee
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSGunnar Hillert
 
How to Create A Magento Adminhtml Controller in Magento Extension
How to Create A Magento Adminhtml Controller in Magento ExtensionHow to Create A Magento Adminhtml Controller in Magento Extension
How to Create A Magento Adminhtml Controller in Magento ExtensionHendy Irawan
 
AnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFacesAnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFacesAnkara JUG
 
Frameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPFrameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPDan Jesus
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 

Similar to Introduction to backbone presentation (20)

WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST APIWordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
 
WordPress as the Backbone(.js)
WordPress as the Backbone(.js)WordPress as the Backbone(.js)
WordPress as the Backbone(.js)
 
Djangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django applicationDjangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django application
 
Gutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesGutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisables
 
Vue routing tutorial getting started with vue router
Vue routing tutorial getting started with vue routerVue routing tutorial getting started with vue router
Vue routing tutorial getting started with vue router
 
React.js or why DOM finally makes sense
React.js or why DOM finally makes senseReact.js or why DOM finally makes sense
React.js or why DOM finally makes sense
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com Backbone
 
Flask – Python
Flask – PythonFlask – Python
Flask – Python
 
WordPress Structure and Best Practices
WordPress Structure and Best PracticesWordPress Structure and Best Practices
WordPress Structure and Best Practices
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAE
 
Avinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPressAvinash Kundaliya: Javascript and WordPress
Avinash Kundaliya: Javascript and WordPress
 
Using WordPress as your application stack
Using WordPress as your application stackUsing WordPress as your application stack
Using WordPress as your application stack
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
Django Vs Rails
Django Vs RailsDjango Vs Rails
Django Vs Rails
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJS
 
How to Create A Magento Adminhtml Controller in Magento Extension
How to Create A Magento Adminhtml Controller in Magento ExtensionHow to Create A Magento Adminhtml Controller in Magento Extension
How to Create A Magento Adminhtml Controller in Magento Extension
 
AnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFacesAnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFaces
 
Frameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPFrameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHP
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 

More from Brian Hogg

Submitting, maintaining and growing a plugin on wp.org
Submitting, maintaining and growing a plugin on wp.orgSubmitting, maintaining and growing a plugin on wp.org
Submitting, maintaining and growing a plugin on wp.orgBrian Hogg
 
Preparing a WordPress Plugin for Translation
Preparing a WordPress Plugin for TranslationPreparing a WordPress Plugin for Translation
Preparing a WordPress Plugin for TranslationBrian Hogg
 
Your WordPress Freelance Business Site
Your WordPress Freelance Business SiteYour WordPress Freelance Business Site
Your WordPress Freelance Business SiteBrian Hogg
 
Things I've Learned About Creating a Premium Plugin
Things I've Learned About Creating a Premium PluginThings I've Learned About Creating a Premium Plugin
Things I've Learned About Creating a Premium PluginBrian Hogg
 
WordPress 4.4 and Upgrading Your Site (without the tears...)
WordPress 4.4 and Upgrading Your Site (without the tears...)WordPress 4.4 and Upgrading Your Site (without the tears...)
WordPress 4.4 and Upgrading Your Site (without the tears...)Brian Hogg
 
Using Actions and Filters in WordPress to Make a Plugin Your Own
Using Actions and Filters in WordPress to Make a Plugin Your OwnUsing Actions and Filters in WordPress to Make a Plugin Your Own
Using Actions and Filters in WordPress to Make a Plugin Your OwnBrian Hogg
 
Things I learned about Stress and Imposter Syndrome in Tech
Things I learned about Stress and Imposter Syndrome in TechThings I learned about Stress and Imposter Syndrome in Tech
Things I learned about Stress and Imposter Syndrome in TechBrian Hogg
 
Pricing and Marketing for Freelancers - How to?
Pricing and Marketing for Freelancers - How to?Pricing and Marketing for Freelancers - How to?
Pricing and Marketing for Freelancers - How to?Brian Hogg
 
Introduction to test driven development
Introduction to test driven developmentIntroduction to test driven development
Introduction to test driven developmentBrian Hogg
 
Working with Geolocation in Wordpress
Working with Geolocation in WordpressWorking with Geolocation in Wordpress
Working with Geolocation in WordpressBrian Hogg
 
Intro to Web Apps using HTML5 and Javascript
Intro to Web Apps using HTML5 and JavascriptIntro to Web Apps using HTML5 and Javascript
Intro to Web Apps using HTML5 and JavascriptBrian Hogg
 

More from Brian Hogg (11)

Submitting, maintaining and growing a plugin on wp.org
Submitting, maintaining and growing a plugin on wp.orgSubmitting, maintaining and growing a plugin on wp.org
Submitting, maintaining and growing a plugin on wp.org
 
Preparing a WordPress Plugin for Translation
Preparing a WordPress Plugin for TranslationPreparing a WordPress Plugin for Translation
Preparing a WordPress Plugin for Translation
 
Your WordPress Freelance Business Site
Your WordPress Freelance Business SiteYour WordPress Freelance Business Site
Your WordPress Freelance Business Site
 
Things I've Learned About Creating a Premium Plugin
Things I've Learned About Creating a Premium PluginThings I've Learned About Creating a Premium Plugin
Things I've Learned About Creating a Premium Plugin
 
WordPress 4.4 and Upgrading Your Site (without the tears...)
WordPress 4.4 and Upgrading Your Site (without the tears...)WordPress 4.4 and Upgrading Your Site (without the tears...)
WordPress 4.4 and Upgrading Your Site (without the tears...)
 
Using Actions and Filters in WordPress to Make a Plugin Your Own
Using Actions and Filters in WordPress to Make a Plugin Your OwnUsing Actions and Filters in WordPress to Make a Plugin Your Own
Using Actions and Filters in WordPress to Make a Plugin Your Own
 
Things I learned about Stress and Imposter Syndrome in Tech
Things I learned about Stress and Imposter Syndrome in TechThings I learned about Stress and Imposter Syndrome in Tech
Things I learned about Stress and Imposter Syndrome in Tech
 
Pricing and Marketing for Freelancers - How to?
Pricing and Marketing for Freelancers - How to?Pricing and Marketing for Freelancers - How to?
Pricing and Marketing for Freelancers - How to?
 
Introduction to test driven development
Introduction to test driven developmentIntroduction to test driven development
Introduction to test driven development
 
Working with Geolocation in Wordpress
Working with Geolocation in WordpressWorking with Geolocation in Wordpress
Working with Geolocation in Wordpress
 
Intro to Web Apps using HTML5 and Javascript
Intro to Web Apps using HTML5 and JavascriptIntro to Web Apps using HTML5 and Javascript
Intro to Web Apps using HTML5 and Javascript
 

Recently uploaded

Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 

Recently uploaded (20)

Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 

Introduction to backbone presentation

  • 1. INTRODUCTION TO BACKBONE.JS WITH WORDPRESS Brian Hogg / @brianhogg
  • 2.
  • 3. AGENDA Why Backbone.js Basics of Backbone.js / Underscore.js End-to-end example plugin (Github)
  • 5. WHY BACKBONE? Enforces some structure on your JavaScript Events system
  • 6. WHY NOT JUST JQUERY? Performance Leveraging the community Re-inventing the wheel Code structure (avoid 1000+ lines of jQuery that "just works")
  • 7. WHAT IS BACKBONE.JS? STRUCTURE (MV*) Uses jQuery, but only hard requirement is Underscore.js
  • 8. WHAT IS UNDERSCORE.JS? UTILITY FUNCTIONS WITH _ _.each _.template Lots more: http://documentcloud.github.io/underscore/
  • 9. TEMPLATES var template = _.template("hello <%= name %>"); var html = template({ name: 'Brian' }); console.log( html ); // "hello Brian" var template = _.template("<strong><%- value %></strong>"); var html = template({ value: '<script>' }); console.log( html ); // "<strong>&lt;script&gt;</strong>"
  • 10. ALTERNATIVES EMBER.JS, ANGULAR.JS, ... Multiple ways of doing similar things. Even in Backbone.JS: “It's common for folks just getting started to treat the examples listed on this page as some sort of gospel truth. In fact, Backbone.js is intended to be fairly agnostic about many common patterns in client-side code.” http://backbonejs.org/#FAQ-tim-toady
  • 11. BACKBONE / UNDERSCORE INCLUDED IN WORDPRESS SINCE 3.5 The "backbone" of the media manager, revisions UI
  • 12. MODELS “Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control. You extend Backbone.Model with your domain-specific methods, and Model provides a basic set of functionality for managing changes.”
  • 13. MODEL EXAMPLE var Post = Backbone.Model.extend({ defaults: { title: "", post_status: "draft" }, initialize: function() { console.log("creating a post"); } }); var post = new Post({ title: "Hello, world", post_status: "draft" }); var title = post.get("title"); // Hello, world var post_status = post.get("post_status"); // draft All models have an id attribute for syncing up with a server
  • 14. LISTENING FOR CHANGES post.on("change:title", function(model) { alert("Title changed to: " + model.get("title")); }); Or in the models initialize with: this.on("change:title", this.titleChanged);
  • 15. VIEWS Used to turn a model into something you can see Always contains a DOM element (the el property), whether its been added to the viewable page or not
  • 16. BARE MINIMUM TO USE BACKBONE var PostView = Backbone.View.extend({ events: { "click .edit": "editPost", "change .post_status": "statusChanged" }, editPost: function(event) { // ... }, statusChanged: function(event) { // ... } }); var postView = new PostView({ el: '#my-form' });
  • 17. VIEW EXAMPLE var PostView = Backbone.View.extend({ tagName: "div", // div by default className: "bbpost", // for styling via CSS events: { "click .edit": "editPost", "change .post_status": "statusChanged" }, initialize: { this.listenTo(this.model, "change", this.render); }, render: { // ... } });
  • 18. RENDERING THE VIEW var template = _.template($("#tmpl-bbpost").html()); var html = template(this.model.toJSON()); this.$el.html(html); return this; // for chaining This uses Underscore.js' _.template, but you can use another!
  • 19. ACCESSING THE DOM ELEMENT this.$el this.$el.html() this.el // From within a parent view var view = new PostView({ model: post }); this.$el.append(view.render().el); this.$ this.$('.title').val()
  • 20. COLLECTIONS Ordered set of models var Posts = Backbone.Collection.extend({ model: Post }); var post1 = new Post({ title: "Hello, world" }); var post2 = new Post({ title: "Sample page" }); var myPosts = new Posts([ post1, post2 ]);
  • 21. POPULATING COLLECTIONS FROM THE SERVER Out of the box, Backbone.js supports RESTful APIs through Backbone.sync(method, model, [options]): create → POST /collection read → GET /collection[/id] update → PUT /collection/id patch → PATCH /collection/id delete → DELETE /collection/id
  • 22. What Backbone expects when fetching/reading the collection: [ { id: 1, title: "Hello, world" }, { ... } ] What this sends: wp_send_json_success( array( 'id': 1, 'title': 'Hello, world' ) ); { success: true, data: [ { id: 1, title: "Hello, world" } ] }
  • 23. So, just override .parse() to accommodate: var Posts = Backbone.Collection.extend({ model: Post, url: ajaxurl, // defined for us if we're in /wp-admin parse: function( response ) { return response.data; } }); // Kick things off $(document).ready(function() { posts = new Posts(); postsView = new PostsView({ collection: posts }); posts.fetch({ data: { action: 'bbpost_fetch_posts' } }); }); Or can override .sync(), or even .fetch()
  • 24. Note on calling .fetch() on page load: “Note that fetch should not be used to populate collections on page load — all models needed at load time should already be bootstrapped in to place. fetch is intended for lazily-loading models for interfaces that are not needed immediately: for example, documents with collections of notes that may be toggled open and closed.” http://backbonejs.org/#Collection-fetch Depends on the situation
  • 25. ROUTERS Used for routing your application's URLs when using hash tags (#)
  • 26. (CONTRIVED) EXAMPLE MANAGING WORDPRESS POST TITLES AND PUBLISH/DRAFT STATUS IN AN ADMIN PANEL DEMO
  • 27. DIRECTORY STRUCTURE plugins/ backbone-js-wp-example/ backbone-js-wp-example.php css/ admin.css js/ collections/ posts.js models/ post.js views/ post.js posts.js
  • 28. MODELS/POST.JS var bbp = bbp || {}; (function($){ bbp.Post = Backbone.Model.extend({ }); })(jQuery); Could set defaults here, if creating new posts
  • 29. BACKBONE-JS-WP-EXAMPLE.PHP /* Plugin Name: Backbone.js WP Example Plugin URI: Description: Basic Backbone.js Example in WordPress to edit basic Post properties Version: 1.0 Author: Brian Hogg Author URI: http://brianhogg.com License: GPL2 */ define( 'BBPOST_VERSION', 1 );
  • 30. BACKBONE-JS-WP-EXAMPLE.PHP SETTING UP ACTIONS class BBPostAdmin { public function __construct() { if ( is_admin() ) { add_action( 'wp_ajax_bbpost_fetch_posts', array( &$this, 'ajax_fetch_posts' ) add_action( 'wp_ajax_bbpost_save_post', array( &$this, 'ajax_save_post' ) ); if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) { add_action( 'admin_menu', array( &$this, 'admin_menu' ) ); if ( isset( $_GET['page'] ) and 'bbpostadmin' == $_GET['page'] ) { add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_scripts' } } } }
  • 31. BACKBONE-JS-WP-EXAMPLE.PHP ADDING THE MENU add_menu_page( 'Backbone JS Post Admin Example', 'Backbone JS Post Admin Example', 'add_users' admin_menu() function
  • 32. BACKBONE-JS-WP-EXAMPLE.PHP ADDING THE SCRIPTS // Add backbone.js models first, then collections, followed by views $folders = array( 'models', 'collections', 'views' ); foreach ( $folders as $folder ) { foreach ( glob( dirname( __FILE__ ) . "/js/$folder/*.js" ) as $filename ) { $basename = basename( $filename ); wp_register_script( "$folder/$basename", plugins_url( "js/$folder/$basename", __FILE__ wp_enqueue_script( "$folder/$basename" ); } } wp_register_style( 'bbpost.admin.css', plugins_url( 'css/admin.css', __FILE__ ), false, ECN_wp_enqueue_style( 'bbpost.admin.css' ); enqueue_scripts() function wp-util gives us the wp.ajax helper function
  • 33. ADMIN PAGE TEMPLATE <script id="tmpl-bbpost" type="text/html"> <div class="bbpost"> <h2> <%- title %> </h2> Post title: <input type="text" class="title" value="<%- title %>" />, Status: <select class="post_status"> <option value=""></option> <option value="publish" <% if ( 'publish' == post_status ) { %>SELECTED <option value="draft" <% if ( 'draft' == post_status ) { %>SELECTED </select> <button>Update</button> </div> </script> <h1>Backbone.js WordPress Post Admin Example</h1> <div id="bbposts"> </div> admin_page()
  • 34. ADMIN PAGE TEMPLATE INDIVIDUAL POST <div class="bbpost"> <!-- will update when the model updates, automatically --> <h2> </h2> Post title: <input type="text" class="title" value="<%- title %>" />, Status: <select class="post_status"> <option value=""></option> <option value="publish" <% if ( 'publish' == post_status ) { %>SELECTED >Published <option value="draft" <% if ( 'draft' == post_status ) { %>SELECTED >Draft</ </select> <button>Update</button> </div> <%- title %> <% } %>
  • 35. VIEWS/POSTS.JS var bbp = bbp || {}; (function($){ bbp.PostsView = Backbone.View.extend({ el: '#bbposts', // Specifying an already existing element initialize: function() { this.collection.bind('add', this.addOne, this); }, addOne: function(post) { var view = new bbp.PostView({ model: post }); this.$el.append(view.render().el); } }); $(document).ready(function() { bbp.posts = new bbp.PostsCollection(); bbp.postsView = new bbp.PostsView({ collection: bbp.posts }); bbp.posts.fetch({ data: { action: 'bbpost_fetch_posts' } }); }); })(jQuery);
  • 36. VIEWS/POST.JS var bbp = bbp || {}; (function($){ bbp.PostView = Backbone.View.extend({ className: 'bbpost', initialize: function() { this.model.on("change", this.render, this); }, render: function() { var template = _.template($('#tmpl-bbpost').html()); var html = template(this.model.toJSON()); this.$el.html(html); return this; }, events: { 'click button': 'updatePost' }, updatePost: function() { this.model.set('title', this.$('.title').val()); this.model.set('post_status', this.$('.post_status').val()); this.model.save(); } }); })(jQuery);
  • 37. BACKBONE-JS-WP-EXAMPLE.PHP FUNCTION TO SEND THE POST DATA if ( ! current_user_can( 'edit_published_posts' ) ) wp_send_json_error(); $posts = get_posts( array( 'post_status' => 'any' ) ); $retval = array(); foreach ( $posts as $post ) { $retval[] = array( 'id' => $post->ID, 'title' => $post->post_title, 'post_status' => $post->post_status, ); } wp_send_json_success( $retval ); ajax_fetch_posts()
  • 38. COLLECTIONS/POSTS.JS var bbp = bbp || {}; (function($){ bbp.PostsCollection = Backbone.Collection.extend({ model: bbp.Post, url: ajaxurl, parse: function ( response ) { // This will be undefined if success: false return response.data; } }); })(jQuery);
  • 39. SAVING OVERRIDE SAVE() IN MODELS/POST.JS var bbp = bbp || {}; (function($){ bbp.Post = Backbone.Model.extend({ save: function( attributes, options ) { options = options || {}; options.data = _.extend( options.data || {}, { action: 'bbpost_save_post', data: this.toJSON() }); var deferred = wp.ajax.send( options ); deferred.done( function() { alert('done'); }); deferred.fail( function() { alert('failed'); }); } }); })(jQuery);
  • 40. BACKBONE-JS-WP-EXAMPLE.PHP SAVING A POST TITLE/STATUS if ( ! $post = get_post( (int) $_POST['data']['id'] ) ) wp_send_json_error(); if ( ! current_user_can( 'edit_post', $post->ID ) ) wp_send_json_error(); if ( wp_update_post( array( 'ID' => $post->ID, 'post_title' => $_POST['data']['title'], 'post_status' => $_POST['data']['post_status'], ) ) == $post->ID ) wp_send_json_success(); else wp_send_json_error(); ajax_save_post() function
  • 41. Extra work to set up initially, but worth it later on!
  • 42. WP-BACKBONE Special versions of Backbone.View (wp.Backbone.View) revisions.view.Frame = wp.Backbone.View.extend({ className: 'revisions', template: wp.template('revisions-frame'), // ... }); Handling of SubViews templates use <# #> instead of <% %> (as PHP can see <% %> as code: see trac for details) See revisions.js for an example
  • 43. RESOURCES https://github.com/brianhogg/backbone-js-wp-example http://backbonejs.org/ http://backbonetutorials.com/ https://github.com/addyosmani/backbone-fundamentals http://kadamwhite.github.io/talks/2014/backbone-wordpress-wpsessions WordPress revisions.js