Reuse a block of code in several places in jinja2

12,004

Solution 1

What you are looking for is called a macro.

Macros are placed in separate files (e.g., macros.html).

{% macro usedalot(somevalue) %}
    <div class="usedalot">{{ somevalue }}</div>
{% endmacro %}

You can then import your macros in other templates

{% from 'macros.html' import usedalot %}

and then use them whenever needed

{{ usedalot(1) }}

This will output

<div class="usedalot">1</div>

Solution 2

As of Jinja 2.8, you can also now use block assignments to map a block (still can only be defined once) to a variable that can be used multiple times in the document.

Documentation is at: Block assignments

I just used the feature to drop my HTML page title block into both the title element as well as the meta property for Facebook's opengraph:title attribute.

{% set title_s %}{% block title %}MY DEFAULT TITLE{% endblock %}{% endset %}
<head>
<meta property="og:title" content="{{ title_s }}" />
<title>{{ title_s }}</title>
...
</head>

This seems to me to be a much more clean solution than defining a macro.

Share:
12,004

Related videos on Youtube

James King
Author by

James King

Updated on September 14, 2022

Comments

  • James King
    James King over 1 year

    I have this html snippet which needs to be used in lots of places in the jinja2 templates:

    <div class="usedalot">{{  somevalue }}</div>
    

    for example, in template1.html, template2.html. template3.html, this code is repeated several places

    <!-- template1.html, template2.html. template3.html -->
    <div class="usedalot">{{  somevalue }}</div>
    ......
    <div class="usedalot">{{  somevalue }}</div>
    ....
    <div class="usedalot">{{  somevalue }}</div>
    ......
    

    Instead of copying and pasting, is there someway to use this code snippet as a block? The jinja2 template inheritance (with blocks) do not seem to solve this problem.

  • Toskan
    Toskan almost 7 years
    that's so incredibly ugly though. I mean it looks ok if your argument is 1. What if your argument is a BIG piece of HTML?
  • dirn
    dirn almost 7 years
    Why are you defining HTML inside a string literal in a template? That sounds like a code smell.
  • Toskan
    Toskan almost 7 years
    no. I am telling, I don't want to do exactly that. The question is: how can I do it? see here stackoverflow.com/questions/45113110/…
  • Someguy123
    Someguy123 over 4 years
    This should be the accepted answer. Works great here in 2019 with Flask :)
  • tarponjargon
    tarponjargon over 4 years
    This is a good solution. I don't believe the {% block title %} {% endblock %} is needed with block assignments
  • kev
    kev about 4 years
    This is just using a variable in multiple places. I think James was after a reusable/parameterisable code block. Sth. like you can call like a function with variables.
  • Andrei-Niculae Petre
    Andrei-Niculae Petre over 3 years
    exactly what I needed - simple and allows variables parametrization. I had to use a block inside it though to make it work, exactly like described.