Skip to main content

A Django template tag for embedding Mustache.js templates safely.

Project description

A templatetag for easier integration of mustache.js JavaScript templates with Django templates. Inspired by ICanHaz.js, django-icanhaz, and jquery.mustache.

Quickstart

Dependencies

Tested with Django 1.3 through trunk, and Python 2.6 and 2.7. Almost certainly works with older versions of both.

Installation

Install from PyPI with pip:

pip install django-mustachejs

or get the in-development version:

pip install django-mustachejs==dev

Usage

  • Add "mustachejs" to your INSTALLED_APPS setting.
  • Set the MUSTACHEJS_DIRS setting to a list of full (absolute) path to directories where you will store your mustache templates. By default this is set to a directory named jstemplates.
  • Set the MUSTACHEJS_EXTS setting to a list of the app should search for to find template files. By default this is set to ['mustache', 'html']. Order matters (e.g., *.mustache will take precedence over *.html).
  • In your HTML header, include mustache/js/mustache-<version>.js. The versions shipped with django-mustache are 0.3.0 and 0.4.0-dev.
  • {% load mustachejs %} and use {% mustachejs "templatename" %} in your Django templates to safely embed the mustache.js template at <MUSTACHEJS_DIRS-entry>/templatename.html into your Django template. It will be stored in the Mustache.TEMPLATES object as a string, accessible as Mustache.TEMPLATES.templatename.
  • In your JavaScript, use Mustache.to_html(Mustache.TEMPLATES.templatename, {...}, Mustache.TEMPLATES) to render your mustache template. Alternatively, if you include the mustache/js/django.mustache.js script in your HTML, you can use Mustache.template('templatename').render({...}) to render your mustache template.

An Example

For example consider the files app/jstemplates/main.mustache:

<div>
  <p>This is {{ name }}'s template</p>
</div>

and app/templates/main.html:

{% load mustachejs %}

<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>

  <script src="{{ STATIC_URL }}mustache/js/mustache-0.3.0.js"></script>
  <script src="{{ STATIC_URL }}mustache/js/django.mustache.js"></script>
</head>

<body>
  <div id="dynamic-area"></div>

  {% mustachejs "main" %}

  <script>
    $(document).ready(function() {

      var $area = $('#dynamic-area')
        , template;

      // Either render by accessing the TEMPLATES object
      // directly...

      $area.html(Mustache.to_html(Mustache.TEMPLATES.main));

      // ...or render by using a cached template object
      // (requires django.mustache.js)

      template = Mustache.template('main');
      $area.html(template.render());

    });
  </script>
</body>
</html>

What’s going on?

Any time you use the mustachejs template tag:

{% load mustachejs %}
{% mustachejs "main" %}

django-mustachejs will generate the following:

<script>Mustache.TEMPLATES=Mustache.TEMPLATES||{};Mustache.TEMPLATES['main']='<div>\n  <p>This is {{ name }}\'s template</p>\n</div>';</script>

This stores the text of the template in an attribute on the Mustache.TEMPLATES object (it will first create the object if it does not yet exist). The Mustache.template(...) function then creates an object with a render(...) method that has a similar signature as Mustache.to_html(...), except without the template name as the first parameter. The render method will also use the set of templates in Mustache.TEMPLATES as partials, allowing any template that django-mustachejs knows about to be used as a template partial as well.

Advanced usage

You can also bundle MustacheJS templates with Django reusable apps; by default django-mustache will look for templates in a jstemplates subdirectory of each app in INSTALLED_APPS. The app subdirectory name(s) to check can be configured via the MUSTACHEJS_APP_DIRNAMES setting, which defaults to ["jstemplates"].

The finding of templates can be fully controlled via the MUSTACHEJS_FINDERS setting, which is a list of dotted paths to finder classes. A finder class should be instantiable with no arguments, and have a find(name) method which returns the full absolute path to a template file, given a base-name.

By default, MUSTACHEJS_FINDERS contains "mustachejs.finders.FilesystemFinder" (which searches directories listed in MUSTACHEJS_DIRS) and "mustachejs.finders.AppFinder" (which searches subdirectories named in MUSTACHEJS_APP_DIRNAMES of each app in INSTALLED_APPS), in that order – thus templates found in MUSTACHEJS_DIRS take precedence over templates in apps.

Rationale (from django-icanhaz)

The collision between Django templates’ use of {{ and }} as template variable markers and mustache.js’ use of same has spawned a variety of solutions. One solution simply replaces [[ and ]] with {{ and }} inside an mustachejs template tag; another makes a valiant attempt to reconstruct verbatim text within a chunk of a Django template after it has already been mangled by the Django template tokenizer.

I prefer to keep my JavaScript templates in separate files in a dedicated directory anyway, to avoid confusion between server-side and client-side templating. So my contribution to the array of solutions is essentially just an “include” tag that avoids parsing the included file as a Django template (and for convenience, automatically wraps it in the script tag that ICanHaz.js expects to find it in).

Enjoy!

CHANGES

0.5.0

  • Add mustacheraw tag to insert just the raw text of a mustacehe template. Thanks to Greg Hinch.
  • Add mustacheich tag to insert a mustache script block as icanhaz expects.

0.4.1 (2012.01.09)

  • Fixed template reading to explicitly decode template file contents using Django’s FILE_CHARSET setting. Thanks Eduard Iskandarov.
  • Fixed template-finding failure with non-normalized directories in MUSTACHEJS_DIRS. Thanks Eduard Iskandarov for report and patch.

0.4.0

  • Add the MUSTACHEJS_EXTS configuration variable for specifying the extensions allowed for template files located by the FilesystemFinder (and, by extension, the AppFinder).

0.3.3

  • Add a package_data value to the setup call

0.3.2

  • Add the MANIFEST.in file itself as an entry in MANIFEST.in.

0.3.0

  • Change the name from django-icanhaz to django-mustachejs.
  • Remove dependency on ICanHaz.js. I like the library, but the maintainers were not responsive enough for now. Use Mustache.js straight, with a little bit of minimal sugar. Templates are rendered to straight Javascript.

0.2.0 (2011.06.26)

  • Made template-finding more flexible: ICANHAZ_DIR is now ICANHAZ_DIRS (a list); added ICANHAZ_FINDERS, ICANHAZ_APP_DIRNAMES, and finding of templates in installed apps.

0.1.0 (2011.06.22)

  • Initial release.

TODO

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for django-mustachejs, version 0.5.0
Filename, size File type Python version Upload date Hashes
Filename, size django-mustachejs-0.5.0.tar.gz (15.0 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page