django-handlebars 0.1
Handlebars for Django
License: BSD
Keywords: django handlebars

=================
django-handlebars
=================
django-handlebars integrates `Handlebars <http://handlebarsjs.com/>`_ JavaScript templating engine with `Django <https://www.djangoproject.com/>`_. It provides Python and JavaScript helpers for wrapping templates inclusion and loading routines. Optionaly django-handlebars provides ``manage.py`` commands facilitating compilation (requires ``python-spidermonkey``) and live templates assets synchronization as you developing (requires ``pyinotify``).

How to install
==============
1. Install package from PyPi ``pip install django-handlebars``. Or alternatively pull the repo and run ``python setup.py install``

2. Add ``django_handlebars`` to project's ``settings.INSTALLED_APPS``

3. Optionaly add ``HANDLEBARS_*`` configuration parameters to the ``settings.py``. See `django_handlebars.appsettings <https://github.com/yavorskiy/django-handlebars/blob/master/django_handlebars/appsettings.py>`_ for available options and explanations

4. Run ``./manage.py test django_handlebars`` to check configuration and requirments.

5. That should be it. Application is not providing any models or URLs.

How to use
==========
django-handlebars can work in two modes: compiling templates in browser and rendering templates pre-compiled on server side. In both scenarios templates might be loaded dynamically with AJAX request or included on page to prevent extra HTTP requests.

First you have to drop in Handlebars scripts on page::

  {% load handlebars_tags %}
  <html>
  <head>
    {% handlebars_scripts %}
  </head>
  <body></body> 
  </html>

Which will add ``handlebars_config`` variable storing configuration, ``script`` tags for ``handlebars.js`` (or ``handlebars.runtime.js`` if ``settings.HANDLEBARS_COMPILED`` is ``True``) and handlebars.django.js. Django-handlebars provides template loading client (see handlebars.django.js) by extending Handlebars object with tpl() method.

Compiling in browser
--------------------
This mode is simpler and doesn't require optional dependencies to be satisfied. But it adds a little overhead. In this case Handlebars will parse  template every other page load and parser script has to be loaded in addition to renderer.

Assuming you have configured application and your Handlebars ``*.html`` templates are accessiable from static URL, your typical usage pattern will look like this::

  var data = {title: "The title", body: "whatever"}

  Handlebars.tpl("your/template/spec", {
      success: function(renderer){
          console.log("Rendered template:", renderer(data));
      },
      error: function(xhr, err){
          console.warn("Ooops, can't load template", err);
      }
  });


Notice that template path doesn't include dir URL and extension. Starting slash is tolerated. ``Handlebars.tpl`` is NOT returning template, having ``success`` callback is the only way to get it.

By default client attempts to use `jQuery <https://github.com/jquery/jquery>`_ if it's available, otherwise it will fall back to it's own simple crossbrowser XHR implementation. In case jQuery is available ``Handlebars.tpl()`` call would return jQuery.Deferred object, so chaining and other benefits may be used::

  var df = Handlebars.tpl("your/template/spec");

  df.done(function(renderer){
      console.log("Rendered template:", renderer(data));
  }).fail(function(xhr, err){
      console.warn("Ooops, can't load template", err);
  });


Loader appends .html extension and pulls file from ``settings.HANDLEBARS_TPL_URL``

Using pre-compiled templates
----------------------------
In this mode your JavaScript code stays same, but client will attempt to pull .js file from ``settings.HANDLEBARS_TPL_URL``. Pre-compiled file contains JS function generated by ``Handlebars.precompile(str_template)``. You can run this command right in a browser console to see how it looks. Django-handlebars provides manage.py commands to build those files in a batch.

Eliminating extra requests
--------------------------
In both cases described above HTTP request will be made, which lowers performance. To avoid that include you templates on page:::

  {% handlebars_template "your/template/spec" %}


This will cache template by calling ``Handlebars.tpl("your/template/spec", tpl)``. Described technique works for both regular and pre-compiled modes.

How to compile
--------------
Run ``./manage.py compilehandlebars --help``::

  --clean               Remove all previously compiled templates
  --watch               Watch for changes within appsettings.TPL_DIR and compile
  --raw                 Do not format output
  --quiet               Run with no output


Django-hadlebars compiles templates by running Handlebars script using `SpiderMonkey <https://developer.mozilla.org/en/SpiderMonkey>`_ and requires `python-spidermonkey <http://pypi.python.org/pypi/python-spidermonkey>`_ package to be installed.

So far ``--watch`` option is available on Linux platform only since it's using `pyinotify <https://github.com/seb-m/pyinotify>`_. Support for other platforms might be added in future.

If either of these two is not installed ``compilehandlebars`` will exit with appropriate error message.

On ``compilehandlebars`` start all template files with mtime newer than compiled file mtime will be re-compiled. If you run command without ``--watch`` compiler exits once all files compiled, otherwise it will hang until you press ``Ctl-C``.

License
-------
Copyright 2012 Sergii Iavorskyi, Licensed new-style BSD. Contains `Handlebars.js <https://github.com/wycats/handlebars.js>`_ copyright 2011 Yehuda Katz. See LICENSE file for more information.