This Django app will provide your Django project with a nice drop-in replacement for the Django template engine shipped with Django.

You will need to download Chameleon to use these template Loaders, you can either use PIP or download it directly from the Chameleon website: http://chameleon.repoze.org/

One you have it installed, there are a few ways you can use the template engine in your Django project. Here is a list of all the included template Loaders and what they do:


This is a drop-in replacement for the default Django filesystem.Loader It will use your existing TEMPLATE_DIRS to load templates.


This is a drop-in replacement for the default Django app_directories.Loader It will use the 'templates' directories in each of your app directories.


This Loader allows you to specify a seperate CHAMELEON_TEMPLATES settings variable, which acts the exact same as your TEMPLATE_DIRS variable.

There are also a couple settings variables you can set as well:


Takes the exact same format as TEMPLATE_DIRS variable. This setting is only valid when the chameleon_engine.Loader is used. It allows you to have a specific directory for chameleon templates.


This forces a specific extension on all template files. This uses the functionality shipped with Chameleon, and merely passes this setting directly over to Chameleon.


You will still render templates using the Django method, such as render_to_response() or render(). You will even have access to all of your usual context variables, including context_processors.

Included in this package are some examples which you can take a look at.
There is an example views.py, and urls.py. To use try out these examples add the following line to your project's urls.py:

url(r'^chameleon/', include('djchameleon.urls')),

You can of course change the base url. The reason why I suggest adding this is so that the included url tag can reverse the url in the example template. Yes, this template drop-in has a Django compatible url method you can use, more on that in the next section.

In order to use these examples you will also need to add djchameleon to your INSTALLED_APPS and use the djchameleon.loaders.app_directories.Loader. In normal operation, you do not need to have this app in your INSTALLED_APPS, only the example template requires it.

Chameleon Django API

Now on to the fun stuff, how to use various Django resources within your Chameleon templates, such as CSRF_TOKEN and URL Reversal. At the moment, these are the only main functions taken from Django as they are a requirement when working with a Django project. The example mentioned above shows both of these in action, but I will explain how to use each one of these APIs here within your template:

URL Reversal:

<a tal:attributes="href url:hello_chameleon">A Link!</a>

If you need to place a URL inside JavaScript, you can use the following notation:



<p metal:use-macro="django.csrf_token" />

This will do exactly what {% csrf_token %} does. You can also render it manually as such:

<input type="hidden" name="csrfmiddlewaretoken" tal:attributes="value csrf_token" />

Adding METAL Macros

Unlike in Django where creating template tags requires Python programming skills, you can easily extend the Chameleon template engine using METAL Macros. These can be either placed in your base template or in your app directories macros/ directory. You can see an example macro in the djchameleon/macros/example.pt file. Everything with a pt extension in your apps macros/ directory is added into the global template namespace.

For example, say your app name is todo, and you want to create a namespace called todo which assists in many aspects of your todo application. This is where you would create the file:


Then inside that file, you can place various reusable HTML/Python code for your todo app templates to use. Here's an example template, which is included in the example.pt file:

<p metal:define-macro="hello">
  Hello, <strong metal:define-slot="name">World</strong>

To use this macro inside any Chameleon template, use one of the following code:

<p metal:use-macro="todo.hello" />

Or if you wish to fill in the name context, use this code:

<p metal:use-macro="todo.hello" >
  <i metal:fill-slot="name">Kevin</i>

Also note that you can also change the underlying tag dynamically, here it's changed from strong to i.