Has anyone found a good solution for developing templates for backbone.js that can be used on the server and the client?
This is really desirable with the backbone.js hi
Here's a very simple example of rendering an Underscore/Backbone template in NodeJS. I've installed Underscore using NPM.
var http = require('http'),
_ = require('underscore');
http.createServer(function (req, res) {
var template = "<h1><%=message%></h1>"
res.end(_.template( template, {message: "Hello world"}));
}).listen(8080, 'localhost');
Try https://github.com/flatiron/plates
Works great in both environments, is DSL free and has a clean API
I have tried numerous solutions, and http://ezeljs.com/ is definitely the simplest and most easy to implement. It just makes sense.
A boilerplate for Backbone projects that share code server/client, render server/client, and scale through modular architecture.
Uses Jade templates, for both the server and the client. Browserify and using a Jade transform, is definitely my preferred method for sharing templates on both the client and the server.
Node.js with nunjucks templating is working well for me because I needed non-XML templating for non-SGML web content (nunjucks allows setting the template delimiters in text templates - which is the case with jinja2 for Python on which nunjucks is a re-eng )
I haven't used it for node, but I've used mustache pretty extensively for backbone.js and been pleased with the results, and it has a port to use it with node as well.
http://mustache.github.com/
You could use JSDOM to render your page with node.js as follows
// specify a catch all route
app.get('/namespace/*', function (req, res, next) {
// load the dom
jsdom.env({
html: html,
src: src,
features: {
FetchExternalResources: false,
ProcessExternalResources: false
},
done: function (err, window) {
// overwrite Backbone's sync method with a server-side one
window.Backbone.sync = sync
window.$(function () {
window.Backbone.history.start({ silent: true })
// load requested url
var matched = window.Backbone.history.loadUrl(req.originalUrl.substr(1))
if (matched) // if matched: return resulting html
res.end(window.document.innerHTML)
else
next()
})
}
})
})
Therefor you also have to specify the following variables
var sync = function(method, model, options, error) {
// your server side sync method
}
var html = fs.readFileSync(path.join(__dirname, 'views/index.htm'), 'utf-8')
var src = [
fs.readFileSync(path.join(__dirname, 'public/javascripts/jquery.js'), 'utf-8'),
fs.readFileSync(path.join(__dirname, 'public/javascripts/underscore.js'), 'utf-8'),
fs.readFileSync(path.join(__dirname, 'public/javascripts/backbone.js'), 'utf-8'),
fs.readFileSync(path.join(__dirname, 'public/javascripts/your-backbone-stuff.js'), 'utf-8')
]
Unfortunately I didn't found a solution to duplicate the created window/document object for reuse.
Also this solutions is only suitable for e.g. search engines because it lacks the client-side mapping from Backbone Views to there corresponding DOM nodes.