Mustache templating tools for integration with Flask.
It assumes the following things:
- You want first-class Mustache template rendering inside your Jinja templates;
- You want to share templates between Javascript and your server;
.mustache
files live alongside your regular Jinja templates;- You're using jQuery on the client.
If you're okay with all of the above, read on.
If Flask-Mustache is installed in your pythonpath
, it'll be
automatically made available under flask.ext
:
from flask.ext.mustache import FlaskMustache
There are two ways to add your app, depending on preference.
# noop style
FlaskMustache(app)
# or as a WSGI-middleware style wrapper
app = FlaskMustache.attach(app)
In both cases the results are the same.
Flask-Mustache is implemented as a
Flask Blueprint so that it
can bring its own Jinja templates and static assets along. One
interesting quirk (bug) of Flask Blueprints is that they can only
serve static assets if
they're configured with a URL prefix.
In the case of Flask-Mustache, that URL prefix is automatically set to
/_mustache
.
Flask-Mustache comes with a jQuery plugin that loads your templates for you in Javascript. To serve this file the regular Flask way:
{{ url_for('mustache.static', filename='mustache-loader.js') }}
or via Flask-Assets:
Bundle('mustache/mustache-loader.js')
and that's it.
This extension provides a global function named mustache
. It takes a
few arguments:
- A path to a template. This path is based on your Flask template
path (it uses the Flask
jinja_env
load path to find templates) - A context object in the form of a dictionary; or
**kwargs
that become the Mustache context.- a dictionary of partials (optional)
Examples:
{{ mustache('includes/_user_profile.mustache', {'user_id':1, 'user_name': 'Bob'}) }}
{{ mustache('includes/_user_profile.mustache', user_id=1, user_name='Bob') }}
{{ mustache('includes/_user_profile.mustache', partials={'welcome_note':'includes/welcome.mustache'}, user_id=1, user_name='Bob') }}
In the last example, _user_profile.mustache
can have a reference to the partial welcome_note
as {> welcome_note}
.
Flask-Mustache provides a jQuery plugin that lets you load templates
off the "filesystem" automatically. To load the above example (no kwargs
in Javascript):
$('<div />').mustache('includes/_user_profile.mustache', {user_id:1, user_name:'Bob'})
Creates a new div
with the contents of whatever Mustache returned.
There are two other ways of using the plugin. The first just returns the rendered HTML (so you can use it however you want):
$('<div />'>.html($.mustache('includes/_user_profile.mustache', {user_id:1, user_name:'Bob'}));
and the second returns a function that can be stored as a variable, for example in the Backbone.js style:
var MyView = Backbone.View.extend({
template: $.mustacheAsFunction('includes/_user_profile.mustache'),
render: function() {
this.$el.html(this.template({user_id:1, user_name:'Bob'}));
}
})
Both of above forms support mustache partials -
var partials = {welcome_note: 'Welcome, \{\{user_name \}\}' };
$('<div />').mustache('includes/_user_profile.mustache', {user_id:1, user_name:'Bob'}, partials=partials)
In the above example, _user_profile.mustache
has reference to the welcome_note
partial with {> welcome_note }
.
The jQuery plugin requires either Hogan.js or Mustache.js in development.
The templates are read off the file system and dropped into the
template by a context processor. After this the Javascript can pick
them up via regular DOM methods. Put this into your main inherited
jinja
template:
{{ mustache_templates }}
and that's it.
Your templates should be pre-compiled in production so you don't tax
the client. You can do this using the Hogan.js binary hulk
,
which is available if you have installed Hogan.js using npm.
hulk
takes a space separated list of files as arguments and outputs
the compiled template javascript to stdout
. You can output this
javascript to a file, e.g.:
hulk templates/includes/_user_profile.mustache > static/compiled_mustache.js
Serve this javascript file in place of the templates rendered by the
jinja
context processor when in production. You will also need to
include the Hogan.js client javascript
If you have a number of templates, and/or you want to make the
pre-compilation part of your deployment process, you might want to
discover the templates and pass them to hulk
programmatically.
This gist shows an example
Flask-Script manager
command that does this.