DRY with Jinja Macros

Jinja is a great templating language that’s used with python. One of the easiest ways to not repeat yourself in Jinja is to use macros.

Let’s say you want to build a blog. You might have something like this

<h1>My Blog</h1>
<h2>Featured Post</h2>
<h3>Why Ponies are Awesome</h3>
<p>
    Ponies are awesome because...
</p>
<h2>Other Posts</h2>
<h3>Where Is My Kitten</h3>
<p>
    Here he is!
</p>
<h3>All the cupcakes</h3>
<p>
    I ate all the cupcakes at Pinterest today.
</p>

You might try to use for loops and variables in Jinja:

<h1>My Blog</h1>
<h2>Featured Post</h2>
<h3>{{ featured_post.title }}</h3>
{{ featured_post.body }}

{% for post in posts %}
    <h3>{{ post.title }}</h3>
    {{ post.body }}
{% endfor %}

A little bit of repetition, which can get annoying if you want to add a date:

<h1>My Blog</h1>
<h2>Featured Post</h2>
<h3>{{ featured_post.title }}</h3>
<span class="date">{{ featured_post.date }}</span>
{{ featured_post.body }}

{% for post in posts %}
    <h3>{{ post.title }}</h3>
    <span class="date">{{ post.date }}</span>
    {{ post.body }}
{% endfor %}

At this point even I’m getting tired of contriving these examples. Enter the macro. Macros can appear anywhere in your template. They don’t render unless they are called so I usually stick them at the veryt top of a page:

{% macro show_post(post) %}
    <h3>{{ post.title }}</h3>
    <span class="date">{{ post.date }}</span>
    {{ post.body }}
{% endmacro %}

<h1>My Blog</h1>
<h2>Featured Post</h2>
{{ show_post(featured_post) }}
{% for post in posts %}
    {{ show_post(post) }}
{% endfor %}

That’s a lot easier. You can think of macros in templates the way you think of functions elsewhere.

For a real world example, you can look at a commit to Amy Lam’s Hackbright project.