Jinja2 Template Filters

Jinja2 Logo

Jinja2 is a templating language for Python that is very similar to Django’s templating system. It is very widely used and was the default templating system that came with Pelican. Coming from a Django background in templating and as a previous Mako templates user I was excited to try it out.

I won’t go into a full break down of differences between Django, Mako, and Jinja2. Quickly then, Mako is compiled into Python modules, essentially writing Python code in your templates. Django is a restrictive templating language built on the idea that you should be putting values, not logic, in your templates. Logic is handled through tags while variables can be transformed through the use of filters. Jinja2 builds off of Django supporting additional filters, tags, and functionality that gives it more power. With power comes responsibility, limit the logic in your templates.

During the transfer from my home-grown static file system I added a few Jinja2 filters to my Pelican configuration. I will expand on the plugins I added later on.

Suffixes for Dates

def suffix (d):
    """Returns a suffix for a given number."""
    sfx = {
        1: 'st',
        2: 'nd',
        3: 'rd'
    }
    return 'th' if 11 <= d <= 13 else sfx.get(d%10, 'th')

I wrote a short helper function because I wanted to be able to output 10th and 1st for dates. I’ve since avoided doing that but it’s helpful nontheless as Python’s built-in strftime are limited.

Period Archive Titles

def archive_fmt (period):
    """Returns an archive formatted date."""
    if len(period) == 1:
        return period[0]
    if len(period) == 2:
        return u"{1} {0}".format(*period)
    return u"{2} {3}{0}, {1}".format(suffix(period[2]), *period)

This enables me to title period archives as Archives for {{ period|archive_fmt }} with minimal work in the template itself.

Post Years

def year_archives (dates):
    """Returns a list of years ordered descending from the given list of
    dates."""
    years = set()
    for article in dates:
        years.add(article.date.year)
    for year in reversed(sorted(years)):
        yield year

This powers the yearly period archives on the homepage.

Transforming Integers to Months

def int_to_month (m_int):
    """Turns an integer month into a long month."""
    d = datetime(year=2014, day=1, month=m_int)
    return d.strftime("%B")

Also used in the period archives to output a long month name.

Translation Support

def lang_to_en (value):
    return {
        "en": "English",
        "zh": "中文",
        "es": "Español",
        "fr": "Français"
    }.get(value, "NO LANGUAGE")

This is a quick helper for when an article has translations. This means each translation link can be represented as the language (中文) instead of the two character language code (zh).

Adding custom filters and extensions to Jinja2 in Pelican is as simple as defining a function and adding it to the JINJA_FILTERS map in your settings.

written August 15th, 2014

August 2014

Can’t find what you’re looking for? Try hitting the home page or viewing all archives.