I'd like to use momentjs (more generally, any other function) as helper in a Jade template, both for the server and the client. On the server (Express.js 3.x), I'm adding it to app.locals, and it works fine:
// Locals
app.locals.moment = require('moment');
// Routes
app.get('/', function (req, res) {
res.render('index.jade')
});
app.listen(config.get('server').port);
So using the moment helper works fine when the template (index.jade) is rendered by the server and then served at / as plain HTML.
On the client (RequireJS modules system) I'm using Backbone.js along with, again, Jade in order to render views. How can I use moment helper in navbar.jade?
define(
['jade', 'backbone', 'text!views/navbar.jade'],
function (Jade, Backbone, navbarTemplate) {
return Backbone.View.extend({
initialize: function () {
this.template = Jade.compile(navbarTemplate);
},
render: function () {
this.$el.html(this.template(this.model));
return this;
}
});
}
);
EDIT: based on Peter Lyons suggestion, I've wrapped compile function. moment works but foo doesn't (p= moment() vs p= foo(), the latter gives me cannot call function of undefined):
define(['jade', 'lodash', 'moment'], function (Jade, _) {
return {
compile: function(str, options) {
options.locals = _.extend({
moment: require('moment'),
foo: function () { return 'bar'; }
}, options.locals);
return Jade.compile(str, options);
}
};
});
When you invoke the compiled template function in the browser, there's no out of the box app.locals, so you would have to code it.
//customJade.js module
define(function (require, exports) {
var jade = require('jade');
var moment = require('moment');
exports.compile = function(jadeString) {
//build the normal jade template function
var jadeFn = jade.compile(jadeString);
//build a wrapper function with same API
var customFn = function(locals) {
//in the wrapper, add your shared locals as needed
locals.moment = locals.moment || moment;
locals.appName = "Super Happy Fun App!";
//return the result of the real jade template function,
//but with combined locals
return jadeFn(locals);
};
//return your wrapper function instead of the regular jade function
return customFn;
}
});
.
//your backbone view module
define(['customJade', 'jadeTemplateString'], function (customJade, jadeTemplateString) {
//blah blah your View subclass...
template: customJade.compile(jadeTemplateString),
//...
});