Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reuse a block of code in several places in jinja2

Tags:

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.

like image 712
James King Avatar asked Jan 22 '14 06:01

James King


People also ask

How are templates reused in Jinja2?

To reuse a Jinja template you use the Jinja built-in {% extends %} tag. The {% extends %} tag uses the syntax {% extends <name> %} to reuse the layout of another template. This means that in order to reuse the layout in listing 4-5 defined in a file base.


2 Answers

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> 
like image 139
dirn Avatar answered Sep 22 '22 12:09

dirn


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.

like image 45
William McVey Avatar answered Sep 22 '22 12:09

William McVey