1. Introduction
django-jinja is a BSD Licensed, simple and nonobstructive jinja2 integration with Django.
Jinja2 provides certain advantages over the native system of Django, for example, explicit calls to
callable from templates, has better performance and has a plugin system, etc …
There are other projects that attempt do same thing: Djinja, Coffin, etc… Why one more?
-
Unlike Djinja, django-jinja is not intended to replace a Django template engine, but rather,
it complements the Django’s template engine, giving the possibility to use both.
-
Unlike Coffin, the django-jinja codebase is much smaller and more modern. This way is much more
maintainable and easily understandable how the library works.
1.1. Features
-
Auto-load templatetags compatible with Jinja2 on same way as Django.
-
Django templates can coexist with Jinja2 templates without any problems.
It works as middleware, intercepts Jinja templates by file path pattern.
-
Django template filters and tags can mostly be used in Jinja2 templates.
-
I18n subsystem adapted for Jinja2 (makemessages now collects messages from Jinja templates)
-
Compatible with python2 and python3 using same codebase.
-
jinja2 bytecode cache adapted for use django cache subsystem.
-
Django 1.8 support out of the box.
2. Requirements
-
Python 2.7, 3.3 or 3.4
-
Django 1.5, 1.6, 1.7 and 1.8
-
jinja2 >= 2.7.0
2.1. Installation
The simplest way to install django-jinja is using pip:
pip install django-jinja
Add add it to django installed apps list:
INSTALLED_APPS += ('django_jinja',)
3. User guide (django <= 1.7)
3.1. Introduction
Since django-jinja supports two ways to setup (mainly for django ⇐ 1.7 and django >= 1.8)
this section tries expain how to setup it for django ⇐ 1.7.
3.2. Quick Setup
The first step for configure django-jinja is replace default
django template loaders:
TEMPLATE_LOADERS = (
'django_jinja.loaders.FileSystemLoader',
'django_jinja.loaders.AppLoader',
)
django-jinja template loaders inherit’s from a django template loaders and works like middleware,
intercepts by predefined condition templates for render with jinja2 engine.
The simplest condition is using file extensions:
DEFAULT_JINJA2_TEMPLATE_EXTENSION = '.jinja'
With this settings, django-jinja intercepts all templates with
.jinja
extension and render them with
jinja2 engine and templates that not matches the .jinja
extension are forwarded to django templates
engine.3.3. Advances settings
3.3.1. Regex based template matching
Additionaly, django-jinja exposes, more advanced matcher, using regular exceptions:
# Same behavior of default intercept method
# by extension but using regex (not recommended)
DEFAULT_JINJA2_TEMPLATE_INTERCEPT_RE = r'.*jinja$'
# More advanced method. Intercept all templates
# except from django admin.
DEFAULT_JINJA2_TEMPLATE_INTERCEPT_RE = r"^(?!admin/).*"
Furthermore, the regex matching also can be combined with the extension based matching, allowing
match by extension and regex in the same time.
3.3.2. Setup autoescape
You can enable or disable autoescaping with
JINJA2_AUTOESCAPE
setting.# Enable/Disable autoescaping (default: True)
JINJA2_AUTOESCAPE = True
3.3.3. Mute url resolve exceptions
Sometimes, you want simply mute exceptions related to url resolving. You can mute exceptions
with the following entry on your settings:
# Mute reverse url exceptions (default: False)
JINJA2_MUTE_URLRESOLVE_EXCEPTIONS = True
3.3.4. Set custom loader
django-jinja by default setups a proper template loader for load templates from
django’s
TEMPLATES_DIRS
and app specific templates. But in some circumstances you
want override completely it. This can be done using the following entry on
your settings:# Set custom loader
import jinja2
JINJA2_LOADER = jinja2.FileSystemLoader(["/some/path"])
3.3.5. Add additional extensions
django-jinja, by default set up a great amount of extensions for make your experience
using jinja in django painless. But if you want add more extesions, you can done
using
JINJA2_EXTENSIONS
:from django_jinja.builtins import DEFAULT_EXTENSIONS
JINJA2_EXTENSIONS = DEFAULT_EXTENSIONS + [
# Your extensions here...
"path.to.your.Extension"
]
3.3.6. Template bytecode cache
django-jinja supports the Jinja2’s template bytecode caching system. Including an implementation
for makes use of Django’s built-in cache framework.
# Enable bytecode cache (default: False)
JINJA2_BYTECODE_CACHE_ENABLE = False
# Cache backend name for bytecode cache (default: "default")
JINJA2_BYTECODE_CACHE_NAME = "default"
# Specify custom bytecode cache subclass (default: None)
JINJA2_BYTECODE_CACHE_BACKEND = "path.to.you.cache.class"
4. User guide (for django >= 1.8)
4.1. Introduction
Since django 1.8, multiple template engine support was added to django, and django-jinja comes
with support for it. Implementing the backend interface and new configuration syntax.
Django also comes with basic jinja backend, but it not has a lot of facilities and integrations
with the rest of django. django-jinja comes to the rescue and add everything missing.
django-jinja comes with that brief list of differences with django’s built-in backend.
-
find the templates as usual in
"<appname>/templates"
directory instead of"<appname>/jinja2"
directory (you can overwrite this behavior, see below).
-
preload template tags.
-
gettext message loading (i18n).
-
support for django context processors.
Note
|
the usage of context processors is not the recommended way anymore, and with django-jinja you can done it setting global data or global constants. See below, in the django 1.8 configuration related section. |
Warning
|
The settings variables used for configure django-jinja for django ⇐ 1.7 does not works if you are using the django 1.8 backend. |
4.2. Quick Setup
This is a quick example of how to configure django-jinja with django 1.8 configuration
formata:
TEMPLATES = [
{
"BACKEND": "django_jinja.backend.Jinja2",
"APP_DIRS": True,
"OPTIONS": {
"match_extension": ".jinja",
}
},
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True
},
]
Note
|
If you are using the default value for app templates directory for django-jinja backend, take cara about the order template engines, because the django-jinja backend by default uses the same directory for the templates that the django template engine. If you put the django engine first every jinja template will be found by the django engine. |
4.3. Advanced options
4.3.1. Regex based template matching
Additionaly, django-jinja exposes, more advanced matcher, using regular exceptions:
"OPTIONS": {
"match_regex": r"^(?!admin/).*", # this is additive to match_extension
}
Furthermore, the regex matching also can be combined with the extension based matching, allowing
match by extension and regex in the same time.
4.3.2. Context processors support
This a helper for make possible use django’s contect processors with jinja2 backend
for django 1.8.
Example setup a bunch of context processors:
"OPTIONS": {
"context_processors": [
"django.contrib.auth.context_processors.auth",
"django.template.context_processors.debug",
"django.template.context_processors.i18n",
"django.template.context_processors.media",
"django.template.context_processors.static",
"django.template.context_processors.tz",
"django.contrib.messages.context_processors.messages",
],
}
As usual, this is a default list of context processors and you can forget
setup them if you do not have own. Furthermore, it is now not recommended way
to setup variables in the context and the purpose of its existence is a help
for migrations.
4.3.3. Custom filters, globals, constants and tests
django-jinja backend offers a helper options for easy setup constants, global
functions, tests and filters:
"OPTIONS": {
"tests": {
"mytest": "path.to.tests.mytestfn",
},
"filters": {
"myfilter": "path.to.filters.myfilterfn",
},
"constants": {
"hello": "hello world",
},
"globals": {
"somefn": "path.to.functions.somefn",
},
4.3.4. Add additional extensions
django-jinja, by default set up a great amount of extensions for make your experience
using jinja in django painless. But if you want add more extesions, you can done
using
extensions
entry on backend options:from django_jinja.builtins import DEFAULT_EXTENSIONS
"OPTIONS": {
"extensions": DEFAULT_EXTENSIONS + [
# Your extensions here...
"path.to.your.Extension"
]
}
4.3.5. Gettext Style
Jinja2 implements two styles of gettext. You can read about it here:
http://jinja.pocoo.org/docs/dev/extensions/#newstyle-gettext.
You can switch to concrete style using the
newstyle_gettext
entry on
backend options:"OPTIONS": {
"newstyle_gettext": True,
}
4.3.6. Overwrite the default app templates directory
As we said previously, django-jinja backend for django 1.8, uses the same directory for templates as
the django template engine. But in some circumstances you may want to change it for use other
directory. You can overwrite the default value with
app_dirname
option:"OPTIONS": {
"app_dirname": "jinja2",
}
4.3.7. Complete example
This is a complete configuration example with django-jinja’s defaults:
TEMPLATES = [
{
"BACKEND": "django_jinja.backend.Jinja2",
"APP_DIRS": True,
"OPTIONS": {
# Match the template names ending in .html but not the ones in the admin folder.
"match_extension": ".html",
"match_regex": r"^(?!admin/).*",
"app_dirname": "templates",
# Can be set to "jinja2.Undefined" or any other subclass.
"undefined": None,
"newstyle_gettext": True,
"tests": {
"mytest": "path.to.my.test",
},
"filters": {
"myfilter": "path.to.my.filter",
},
"globals": {
"myglobal": "path.to.my.globalfunc",
},
"constants": {
"foo": "bar",
},
"extensions": [
"jinja2.ext.do",
"jinja2.ext.loopcontrols",
"jinja2.ext.with_",
"jinja2.ext.i18n",
"jinja2.ext.autoescape",
"django_jinja.builtins.extensions.CsrfExtension",
"django_jinja.builtins.extensions.CacheExtension",
"django_jinja.builtins.extensions.TimezoneExtension",
"django_jinja.builtins.extensions.UrlsExtension",
"django_jinja.builtins.extensions.StaticFilesExtension",
"django_jinja.builtins.extensions.DjangoFiltersExtension",
],
"autoescape": True,
"auto_reload": settings.DEBUG,
"translation_engine": "django.utils.translation",
}
},
]
5. Differences
5.1. Url reversing
django-jinja comes with helpers for reverse urls. Instead of using the django’s approach, it uses
a simple function called
url
.
Reverse urls in templates
{{ url('ns:name', pk=obj.pk) }}
This approach is very flexible, because we do not need additional options for set a result
if executing url in one variable. With jinja2 you can use the set template tag for it:
{% set myurl=url("ns:name", pk=obj.pk) %}
5.2. Static files
Like urls, the static files can be resolved with simple
static
function available globally
in jinja context:
Example resolving static files
{{ static("js/lib/foo.js") }}
5.3. i18n support
django-jinja inherits the jinja2 approach for handle translation strings. You can read more about
it here: http://jinja.pocoo.org/docs/dev/templates/#i18n
{{ _('Hello %(name)s', name=user.name) }}
{% trans name=user.name %}
Hello {{ name }}
{% endtrans %}
Additionally, django-jinja extends the django’s
makemessages
command for make it work
with jinja2 i18n tags.
If you want more django like i18n related tags, you can use extensions from
https://github.com/MoritzS/jinja2-django-tags.
5.4. Replace jinja filters with django versions
Django and Jinja overlaps in a little subset of template filters. For handle proper this, django-jinja
gets the decistion to use the jinja versions. But if you want a django version of them, you should use
the "django_jinja.builtins.extensions.DjangoExtraFiltersExtension" extension.
The affected filters are: title, upper, lower, urlencode, urlize, wordcount, wordwrap, center
join, length, random, default, filesizeformat, pprint.
5.5. Registring filters in a "django" way.
django-jinja comes with facilities for loading template filters, globals and tests
from django applications.
Here an example:
# <someapp>/templatetags/<anyfile>.py
# don't forget to create __init__.py in templatetags dir
from django_jinja import library
import jinja2
@library.test(name="one")
def is_one(n):
"""
Usage: {% if m is one %}Foo{% endif %}
"""
return n == 1
@library.filter
def mylower(name):
"""
Usage: {{ 'Hello'|mylower() }}
"""
return name.lower()
@library.filter
@jinja2.contextfilter
def replace(context, value, x, y):
"""
Filter with template context. Usage: {{ 'Hello'|replace('H','M') }}
"""
return value.replace(x, y)
@library.global_function
def myecho(data):
"""
Usage: {{ myecho('foo') }}
"""
return data
@library.global_function
@library.render_with("test-render-with.jinja")
def myrenderwith(*args, **kwargs):
"""
Render result with jinja template. Usage: {{ myrenderwith() }}
"""
return {"name": "Foo"}
from .myextensions import MyExtension
library.extension(MyExtension)
5.6. Render 4xx/500 pages with jinja
django-jinja also provides a set of views for easy
render 4xx/500 pages using jinja engine:
# yourproject/urls.py
from django_jinja import views
handler400 = views.BadRequest.as_view()
handler403 = views.PermissionDenied.as_view()
handler404 = views.PageNotFound.as_view()
handler500 = views.ServerError.as_view()
6. Known Issues
-
Previously to django 1.8, some way of using i18n related functions are not properly
parsed with makemessages.
7. Builtin contrib modules
django-jinja comes with some additional contrib modules that adapts limited set of external
django apps for use it easy from jinja templates. Please note that in order to use any of these
contrib modules, you’ll need to install the relevant dependent package yourself first.
Note
|
In django, creating new tags is simpler than in Jinja2. You should remember that
in jinja tags are really extensions and have a different purpose than the django template tags.
Thus for many things that the django template system uses tags, django-jinja will provide
functions with the same functionality.
|
7.1. django-pipeline
Pipeline is an asset packaging
library for Django (official description).
Warning
|
This plugin is deprecated, django-pipeline is come with good jinja support and it
should be used.
You can use the native django-pipeline suport for jinja using the
"pipeline.jinja2.ext.PipelineExtension" extension.
|
Activate plugin (settings.py)
INSTALLED_APPS += ('django_jinja.contrib._pipeline',)
Usage
{{ compressed_css("alias") }}
{{ compressed_js("alias") }}
7.2. easy-thumbnails
Easy Thumbnails is a thumbnail generation library for Django.
Activate plugin (settings.py)
INSTALLED_APPS += ('django_jinja.contrib._easy_thumbnails',)
Usage
{{ thumbnail(file, size=(400, 400)) }}
{{ user.avatar|thumbnail_url("alias") }}
7.3. django-subdomains
Subdomain helpers for the Django framework, including subdomain-based URL routing.
Activate plugin (settings.py)
INSTALLED_APPS += ('django_jinja.contrib._subdomains',)
Usage
{{ url('homepage', subdomain='wildcard') }}
7.4. humanize
Django comes with humanize library that exposes some useful template filters.
Activate plugin (settings.py)
INSTALLED_APPS += ('django_jinja.contrib._humanize',)
No comments:
Post a Comment