Backbone.js and Joomla
- TodoMVC Backbone Example…Where?
- Build the Single Page Application Markup
- Understanding Backbone
- Setting the Collection URL
- Specialising the JSON output
- Saving new Tasks: Handling CSRF tokens
- Let’s Save a ‘task’ to our List
- Wrapping up
Create a Backbone.js powered client-side app and use Joomlatools Framework to provide the REST service backed. To get started quickly, we will use our existing example Joomlatools Todo extension and make use of the Backbone.js example that is part of TodoMVC.
For this tutorial we will assume you have the Joomlatools Vagrant Box running locally. Also, you should have completed the Joomlatools Framework Getting started tutorial to make sure you have some of the core concepts covered.
If not, make sure you have at least the Box running and know how to use the Joomla console. You can find detailed instructions on the Joomlatools developer site. Assuming that your box is up and running, simply start an SSH session with
We are going to create a fresh Joomla install for this tutorial. Run the following Joomla Console command:
Last, we are going to use Composer to install a special branch of our Joomlatools Todo package. This one has the TodoMVC Backbone package already included and ready for use to make our changes.
The ‘318740f1221e4c3b1d7642ce1a1162a0460cc4e4’ is the revision number of the tutorial starting point. We’ve included a similar Composer command at the end of each section. You can choose to follow along and do the coding yourself, or just see the changes by running those commands. If you just want to use the finished code simply remove the ‘#’ and everything after.
With all that done we can get to work powering the todo list with data from the Joomlatools Framework back end.
TodoMVC Backbone Example…Where?
/media/com_todo/lib/backbone directory for you already.
Create the “Backbone” View and Controller
There are a number of approaches that you can take to serve up your single page application. We are going use PHP to produce and serve the initial HTML markup and assets by adding a new ‘View’ to the
An advantage to using PHP to render our page is the potential to send the initial payload of data along with the original page request, instead of having to do another round trip to the server.
Here are the steps:
- Add a new directory to the
/site/components/com_todo/views/directory view called backbone
- Then add another tmpl to that directory;
- Finally, add a new file called
- Place the following code in
Without this last step any call to get our new view will fail miserably. In order for a request to
view=backbone to work we also need to create an empty controller that extends
Joomlatools Framework’s default controller is
KControllerModel, and as such, expects to receive data from a database connected model. We don’t have a table so we need to extend directly from KControllerView which doesn’t expect a model, only a view.
At this point, your new file structure should look something like :
If you now go to http://joomla.box/todo/component/todo/backbone you should see an empty component area.
composer require joomlatools/joomlatools-todo:dev-tutorials/backbone#2251f54cee839856e8291f1316ac2e599bc853c5
Build the Single Page Application Markup
To begin to show the application’s Todo list, we take the inner html of body tag from the existing
- place the contents of the
<body>tag into our new file at
data-inlineto all of the
<script>tags, including those of
- update all the
srcattributes of the scripts with the new locations of their respective resources, using the
Note, you can remove the jquery.js reference, and be sure to be sure to note
backbone.localStorage.jsasset has been moved to
- Add these two
We need to add
data-inline to the script tags to ensure that the scripts stay in place and aren’t filtered and placed in the
<head> tag of the page which would happen otherwise.
Pointing your browser now to http://joomla.box/todo/component/todo/backbone should show you:
At this point everything looks nice and does store todo list items to ‘localstorage’ in your browser, because the TodoMVC example has that implemented out of the box. To implement our Joomlatools Framework powered persistence we’ll need to tell Backbone where to go.
composer require joomlatools/joomlatools-todo:dev-tutorials/backbone#b507a4bf13604c5e4fd22173cd35111e34f0980d
Models represent one entity item, containing a representation your application data. You can think of it as one row object in your database. The Model holds processing logic for that data as well.
Collections are lists or sets of Models but they can and do hold more processing logic as it relates to these lists.
Backbone.sync defines how the library deals with persisting data to the server. Both the Backbone.js Model and Collection objects have a
sync method that proxy
Backbone.sync by default.
We have the ability to change the persistence strategy by overriding this method. For example, we would want to extract the
entities property of Joomlatools Framework’s default response and populate the model or collection
attributes property. We may wish to store some of the other top level properties as similarly named properties in the model or collection.
The most relevant piece of the server persistence strategy of Backbone are the respective
url properties of the Collection and Model. The framework assumes that the Collection’s url will be the plural representation, and that a specific model can be requested by attaching the
id to the end of that url. For example, if the endpoint for a list of todos was /todos/, then the first todo could be accessed through /todos/1.
Backbone.sync method uses underscore’s nifty
result method to process the url property of both in the same way.
_.result(object, property, fallback) figures out if that property is a function and executes it if so, otherwise it simply returns the value of the property. Because of this you can define more complex url strategies, which is exactly what the default
Backbone.Model.url property does.
Backbone.Model.url() is in fact a function and uses
_.result in succession to check if a
urlRoot property is present in the Model, or whether the Collection that is associated with this Model has a
url property defined; either of which must be true or an error will get registered in the console.
Setting the Collection URL
With all that new Backbone knowledge we see that we need only define the TodosCollection url property in
You can open http://joomla.box/todo/component/todo/tasks/?format=json in the browser to see the JSON response at any time.
composer require joomlatools/joomlatools-todo:dev-tutorials/backbone#255a0d26bb3ce0a0036b85f82f38a8c811a4a477
Specialising the JSON output
The response that Joomlatools Framework returns out of the box extends the JSON API standard and has more information than the Backbone needs or expects. Backbone expects responses to GET requests for collections to be returned from the server as a JSON array of models (JSON objects).
It also expects a request for a singular item to be returned as a plain JSON object (without the JSON API spec meta, limits, etc).
We’ve already discussed one option above in changing
Backbone.sync, but we can also override the schema of the JSON that our Todo package returns from the server. Since we are focusing here on how Joomlatools Framework can fit into what the client side needs, we’ll do just that. We can adjust the JSON response by creating our own view classes in the Todo package for
task for that format.
Here’s an example for the singular
task response that you should place at
We also need to create the plural form by extending
ComTodoViewTaskJson so we get to use the same
_actionRender method. Place the following code in a new file at
Great! Now Backbone.js will get the response schema it’s looking for. Refresh your browser: all the tasks that came installed with com_todo should now show up in the list:
composer require joomlatools/joomlatools-todo:dev-tutorials/backbone#5d826b846da44770f93bf05655d555c265b07a68
Saving new Tasks: Handling CSRF tokens
Joomlatools Framework aims to do as much for you out of the box as it can, and so adds some security when it comes to saving data to the server. To make ‘not safe’ requests, i.e. POST, PUT or DELETE methods, a user must be logged in by default; and you must send a valid CSRF Token along with the request.
The Joomlatools Framework HTTP Dispatcher adds the the ‘X-CSRF-Token’ header and
csrf_token cookie to each GET request, so its available for us to use.
We handle that readily by getting and storing that csrf token from the response headers of the GET requests Backbone initiates; then we can add that same token to all ajax requests sent through jQuery Ajax object, i.e. Backbone.$.ajax.
/media/com_todo/lib/backbone/csrf.js and add these two Ajax event handlers.
With that code in place we add a script tag to our
default.html.php layout, right after the loading of backbone.js:
If you are using the Vagrant setup mentioned above you can simply login with
composer require joomlatools/joomlatools-todo:dev-tutorials/backbone#fbbedf2d1ec66e9a7187875f9a6a296e130d6653
Let’s Save a ‘task’ to our List
We are finally at the point where we can save a task to our list. Open your inspector, and look for the tab that shows you all of the page’s requests. Then try adding an item to your todo list. You should see a new request with
POST as its method and if all goes well the server should respond with
201 Created status message:
That’s it in a nutshell! We have integrated the TodoMVC Backbone.js example with the Joomlatools Framework example Todo Extension. The modifications are actually quite minimal. Most of the work was done in changing the schema of the JSON response with the new JSON View class to match the output expected by Backbone. Let’s recap the steps:
- We created a new App View layout and empty controller, because we need no database table.
- We changed the way com_todo formats the JSON output to match what Backbone.js expects.
- We changed the
urlproperty of the
TodoCollectionto our component’s todo collection view.
Let our developers personally assist you. You can ask development related questions in our Support Center. Only for Business or Agency subscribers.
- Getting Started
- Digging Deeper