Inspired by ctemplate and et, Mustache is a framework-agnostic way to render logic-free views.
As ctemplates says, "It emphasizes separating logic from presentation: it is impossible to embed application logic in this template language."
Pystache is a Python implementation of Mustache. Pystache requires Python 2.6.
The different Mustache tags are documented at mustache(5).
git clone http://github.com/dmfrancisco/django-pystache cd django-pystache python setup.py build python setup.py install
>>> import pystache >>> pystache.render('Hi {{person}}!', {'person': 'Mom'}) 'Hi Mom!'
You can also create dedicated view classes to hold your view logic.
Here's your simple.py:
import pystache class Simple(pystache.View): def thing(self): return "pizza"
Then your template, simple.mustache:
Hi {{thing}}!
Pull it together:
>>> Simple().render() 'Hi pizza!'
The mustache spec does not have a tag for i18n. Support was later added to mustache.js by Twitter using the {{_i}}{{/i}} tags (see https://github.com/twitter/mustache.js). This fork adds the same feature to pystache. Check the examples/translation.py file for more information.
If you use the "makemessages" django command, you may want to get the translation strings from your mustache templates. Copy the management directory in this repository to your apps' directory and issue the makemessages command as usual with the additional "-e .mustache" parameter. Example:
python ../manage.py makemessages -l pt_PT -e .mustache
Keep in mind that, at this moment, translation blocks must not include other block tags. For example, this does not work:
{{_i}}{{name}} is using mustache.js!{{/i}}
You can also pre-render translations in the server by using the "pre_render_i18n" method. Check the example below.
# views/application.py from django.utils import simplejson as json from django.http import HttpResponse import pystache pystache.View.template_path = relative('..', 'templates') # Define where the templates are kept pystache.View.template_encoding = 'utf8' # Define encoding class View(pystache.View): ''' Main View class ''' def __init__(self, *args): super(View, self).__init__() ... # Set common local variables, layout, ... @classmethod def template(cls, request, **args): ''' Return raw template ''' template = pystache.Loader().load_template(cls.template_name, cls.template_path) return HttpResponse(template) @classmethod def template_pre_rendered(cls, request, **args): ''' Return raw template with pre-rendered translation sections ''' template = pystache.Loader().load_template(cls.template_name, cls.template_path) template = pystache.Template(template).pre_render_i18n() # Pre-render translation sections return HttpResponse(template) @classmethod def json(cls, request, **args): ''' Return data to render template on the client-side ''' view = cls(request, **args) return HttpResponse(json.dumps(vars(view)), 'application/json') # views/users.py class Edit(View): ''' Example View class ''' template_path = os.path.join(pystache.View.template_path, 'users') def __init__(self, *args): super(Edit, self).__init__() ... # Set local variables @classmethod def view(cls, request, **args): ''' Return the rendered page ''' view = cls(request, **args) ... # Do stuff return HttpResponse(view.render()) ... # urls.py urlpatterns = patterns('', ... url(r'^user/edit$', users.Edit.view), url(r'^user/edit\.mustache$', users.Edit.template_pre_rendered), url(r'^user/edit\.json$', users.Edit.json), ... ) # locale/.../django.po #: templates/users/edit.mustache:18 msgid "My internationalized string!" msgstr "A minha string traduzida!"
nose works great!
pip install nose cd pystache nosetests
- Create an example Django project
- Add tests for internationalization
context = { 'author': 'Chris Wanstrath', 'email': 'chris@ozmm.org' } pystache.render("{{author}} :: {{email}}", context)
Original "makemessages" command reimplementation by altunyurt (djtemps project)