Skip to content
/ jinjet Public

Static generator for Jinja2 templates with localized site tree at /<language> for each available localization.


Notifications You must be signed in to change notification settings


Folders and files

Last commit message
Last commit date

Latest commit



7 Commits

Repository files navigation


Static generator for Jinja2 templates with localized site tree at /<language> for each localization. The output is static and deployable. I created this script because I missed Jinja2 block based templating and the Babel localization framework when using HTML5 frontend assemblers.

Code is adapted from Armin Ronacher's Flask-Babel extensions.


$ pip install git+git://

Using jinjet

I'm using brunch to assemble the frontend. This guide will assume the same, but you can use this for any directory of templates to generate a static localized site tree.

Brunch has the concept of assets, a folder of stuff that doesn't need to be compiled or processed. Assets are copied to the root of the output directory on generation. For this guide we'll render from the asset directory and output to the public folder just like Brunch.

First create some templates:

$ tree app/assets
├── hi.html
└── index.html

hi.html is a template that extends index.html.

{% extends "index.html" %}

{% block content %}
  {{ _('Hi') }}! {{ now.year }}
{% endblock %}

Consult the Jinja template documentation for more information on extending blocks and the syntax.


We're going to use the excellent pybabel utility to manage translation catalogs. It will need a mapping file to search for translation strings.

$ cat babel.cfg
[jinja2: **/assets/**.html]

Extract the translation strings into messages.pot:

$ pybabel extract -F babel.cfg -o messages.pot .

Create a locale for each additional language inside a translations directory:

$ pybabel init -i messages.pot -d translations -l de

Now edit the translations/de/LC_MESSAGES/messages.po file as needed. Compile the translation into a gettext catalog file (.mo):

$ pybabel compile -d translations

Consult the Babel documentation if you are lost.

Running jinjet

Now run jinjet over the asset directory with the same output path as brunch. It will override the public directory with rendered versions of the same templates in the default locale, and a subdirectory for each additional locale.

$ jinjet -v
Processing locale: de
Processing locale: en

jinjet --help will show you some options, mostly for directory names.

Let's see what jinjet generated.

$ tree public/
├── hi.html
├── index.html
├── de
│   ├── hi.html
│   └── index.html
├── en
│   ├── hi.html
│   └── index.html
├── javascripts
│   ├── app.js
│   └── vendor.js
└── stylesheets
    └── app.css

If you look at public/de/hi.html you should see the template, extended from index.html with the strings translated. Jinja2 block based templating and Babel translation FTW. The root templates are left intact so you might want to redirect from the root to a default locale in the server conf. Jinja2 HTML templates are not pretty in the browser.

Template Context

jinjet renders all templates with this context for you to play with.

  • now:
  • current_locale: The current <Locale> object
  • locales: List of all available locales

The locale object has some useful properties, namely language, display_name and tools to get the right scientific formatting and localized date strings. Loop over locales to display a list of available language translations on your site:

<div class="language-picker">
  {% for locale in locales if locale != current_locale %}
  <a href="/{{ locale.language }}/" class="btn">{{ locale.display_name }}</a>
  {% endfor %}

Missing Features

  • Output a CoffeeScript translation catalog for all locales, or compiled Eco and Handlebars templates for all locales.
  • Add date and currency template filters like Flask-Babel.



  • Run without translations catalog; useful for using Jinja2 features but not translated sites.


  • --watch


  • Initial Release


Static generator for Jinja2 templates with localized site tree at /<language> for each available localization.







No releases published


No packages published