-
Notifications
You must be signed in to change notification settings - Fork 16
Getting Started In Backbone
Backbone is a fairly popular Javascript MVC-thingy that commonly uses templates to render the views. Integrating Plate into Backbone is easy, which has the pleasant side-effect of asynchronous renders, ensuring that no one view holds up the show.
Build Plate in the same manner as suggested on Getting Started / in Browser.
Bring in the necessary scripts, and setup a template using type="text/html"
:
<script type="text/javascript" src="/js/underscore-1.3.0.min.js"></script>
<script type="text/javascript" src="/js/backbone-0.5.3.min.js"></script>
<script type="text/javascript" src="/js/plate.js"></script>
<script id="entry-template" type="text/html">
<h2>{{ title|capfirst }}</h2>
<p>
{{ content|linebreaks }}
</p>
<div class="meta">
Posted on {{ pub_date|date:"F j, Y" }} by {{ user.username }}.
</div>
</script>
In your code (which can be included inline in a script tag:
// Use this loader (from https://github.com/chrisdickinson/plate/wiki/Getting-Started---In-Browser)
// to make ``include`` & ``extends`` work with ``<script type="text/html">`` style tags.
plate.Template.Meta.registerPlugin(
'loader',
function(templateName, ready) {
var target = $('#'+templateName);
if(target.length) {
ready(null, new plate.Template(target.text()));
} else {
ready(new Error('Could not find '+templateName));
}
}
)
window.BlogEntryView = Backbone.View.extend({
// Different here!
template: new plate.Template('{% extends "entry-template" %}'),
// Normal...
tagName: 'div',
className: 'entry',
initialize: function() {
_.bindAll(this, 'render');
},
// Different here too!
render: function() {
var self = this;
this.template.render(this.model.toJSON(), function(err, data) {
$(self.el).html(data);
});
return this;
}
});
// You'd do something better abstracted, but for example purposes...
var entry = new window.Entry({id: 35});
entry.fetch({
success: function(model, response) {
// The newly-fetched & populated entry.
var be = new window.BlogEntryView({model: model});
// The append happens immediately, so the element is there but may not be done rendering
// yet. However, when it finishes, since it was passed by reference, it will be updated
// in the DOM.
$('#content').append(be.render().el);
}
});
There are important bits here. The first is the new plate.Template('{% extends "entry-template" %}')
(which loads the template source from the <script id="entry-template" type="text/html">
tag).
The second is the actual rendering. Like normal, we hand the template the models. Because there's a callback involved (remember, Plate is asynchronous), we lose this
when we enter the callback, so we use the closure & stash this
into the self
variable for later use. Once we're in the callback, we've got the rendered
data which we can inject into the element with the $(self.el).html(...)
call.