3

In jinja2, I am trying to dynamically create a html document using the template more than once. My python script looks like this:

# In my python script
env = Environment()
env.loader = FileSystemLoader('.')
base_template = env.get_template('base_template.html')

# each has the actual content and its associated template 
content1 = ("Hello World", 'content_template.html') 
content2 = ("Foo bar", 'content_template.html')


html_to_present = [content1[1], content2[1]]

# and render. I know this is wrong 
# as I am not passing the actual content, 
# but this is the part I am struggling with. More below
base_template.render(include_these=html_to_present, ).encode("utf-8"))

And my base template looks like this:

#################
# base_template.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    {% for include_this in include_these %}
    {% include include_this %}
    {% endfor %}    
</body>
</html>

and content_template.html looks like this

# content_template.html
<div>
    {{ content }}
</div>

Now my question is how do you dynamically set content variable in the content_template.html based on the value associated with it?

Alby
  • 5,522
  • 7
  • 41
  • 51

1 Answers1

6

Use Jinja2 macros to parameterise your templates.

A macro is like a Python function; you define a template snippet, plus the arguments it takes, and then you can call the macro just like you would a function.

I'd put the macros together into one macro template and import that template into your base template. Pass in the names of the macros you want to use to the base template:

# content and macro name
content1 = ("Hello World", 'content_template') 
content2 = ("Foo bar", 'content_template')

base_template.render(include_these=[content1, content2]).encode("utf-8"))

This adds the macro context filter to the environment as well.

and in your base_template.html have:

{% import "macros.html" as macros %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    {% for content, macroname in include_these %}
    {% macros[macroname](content) %}
    {% endfor %}
</body>
</html>

and the macros.html template:

{% macro content_template(content) -%}
<div>
    {{ content }}
</div>
{%- endmacro %}
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343