Jinja2, while a great replacement for Django templates, is not a drop-in replacement for it. I wanted to use Photologue with my Jinja templates, but because Photologue uses Django generics, so I decided to see if I could use Jinja2 with generics, and then only modify the templates. It was a bit of work, but I seem to have done it. Django generics can take template_loader as an option, so if you have the same interface, things should just work.
The template must accept RequestContext as an argument to render(), so here we subclass jinja2.Template and when it receives Django's RequestContext object, it creates a flat dictionary from it, which jinja2 can work with.
A simple macro system that makes it possible to reuse previously defined
blocks, optionally with a custom context, similar to the macro
functionality in Jinja.
It requires some workarounds/hacks because we cannot reach
all the data from inside the django template system that we need, but it
seems to work pretty well so far. It is, however, also pretty untested at this point, so use at your own risk.
Examples:
base.html:
<!--
This is mandatory if you want to use the repeat-tag in
a template. It should as placed as earily as possible.
See below for how to mix with template inheritance.
-->
{% enablemacros %}
<!-- Note that {{ param }} does not exist. -->
{% block foo %}
A standard django block that will be written to the output.
{% if param %}{{ param }}{% endif %}
{% endblock %}
{% macro bar %}
Pretty much the same thing as a django block (can even be
overridden via template inheritance), but it's content
will NOT be rendered per default. Please note that it
ends with ENDBLOCK!
{% if param %}{{ param }}{% endif %}
{% endblock %}
<!-- Render foo for the second time -->
{% repeat foo %}
<!-- Render foo bar the first time -->
{% repeat bar %}
<!-- Render both blocks again, and pass a parameter -->
{% repeat foo with "Hello World" as param %}
{% repeat bar with "Hello World" as param %}
{% macro form %}do stuff with: {{ form }}{% endblock %}
{% for form in all_forms %}
{% repeat display %} <!-- will have access to {{ form }}
{% endfor %}
extend.html:
<!--
{% extends %} requires that it be the first thing in a template,
and if it is, everything except for block tags is ignored, so
{% enablemacros %} won't work. Instead, use:
-->
{% extends_with_macros 'base.html' %}
{% block foo %}
Will override "foo" in base.html
{% endblock %}
{% block bar %}
Will override the macro block "bar" in base.html. Whether
this is defined as block or macro doesn't matter.
{% endblock %}
Todo:
* This (both tags used) results in infinite recursion:
{% extends_with_macros "somefile" %}{% enablemacros %}
- templates
- macro
- jinja
- repeat
- reuse
- variables
Jinja2 is an alternative template system that can be plugged into django.
It offers greator flexibility in presentation logic; if you find the django template system too restrictive, you should have a look at Jinja2
(The syntax is very similar).
In Jinja, you don't need costum tags (most of the time), because you can call functions and pass them parameters too!
The only problem is that you cannot "load" functions from the template, this "loading" must be done by the code that renders the template. Same goes for filters and tests.
If you need only two or three functions/filters, no problem, you can manually add them to the Environment object; but this method doesn't really scale with real-life webapps.
This module/snippet offers a solution by allowing the user to define application-specific functions and filters and load them into the jinja2 environment automatically.
Here's how to use this:
1. Install Jinja2 (for a quick & dirty installation, you can just put the jinja2 folder in a folder that's in PYTHONPATH)
2. Save this python module somewhere and call it something meaningful (I have it as jinja.py in my project directory)
3. Whenever you need to respond (an HttpResponse) with a template that's rendered by jinja, import this module and call `return jrespond( template_name, context )`
4. Any filters or functions you define in any of your applications will be readily available inside the template (see the documentation in code)
- template
- templates
- jinja
- template-tags
- jinja2