Search code examples
htmlpython-3.ximagetemplatesjinja2

Adding multiple images to a html file using Jinja2


I am trying to load and add multiple figures from disk to a HTML file

For adding a single image, I tried the following (ref.: Jinja2/Python insert a image(s) into html)

import jinja2

env = jinja2.Environment(
        loader=jinja2.FileSystemLoader('.'),
        trim_blocks=True,
        lstrip_blocks=True,
    )

template = env.get_template("template.html")
template_vars = {"title":"TITLE", "graph":'obj.png'}

text = template.render(template_vars)
with open("test2.html", "w") as f_out:
    f_out.write(text)

The template looks like the below

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>TITLE</title>
</head>
<body>
<h2>Graph Goes Here</h2>
<img src="obj.png">
</body>
</html>

To extend this to add multiple images, I made the following modification in the template

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
<h2>Graph Goes Here</h2>
<dl>
{% for key, value in template_vars.items() %}
 <img src="{{value}}.png">
{% endfor %}
</dl>
</body>
</html>

I would like to know how

template_vars = {"title":"TITLE", "graph":'obj.png'}

has to be modified to pass multiple figures.


Solution

  • You will need to update the object type used for your variable template_vars to make things simpler to iterate. Instead of a dictionary, you likely want a list of dictionaries so that you will be able to loop over each image and get multiple attributes for each one (in your case, a value for the key title and another one for the key graph). You should also refer to your variable when calling template.render so that Jinja2 knows what you are writing about (i.e., replace template.render(template_vars) with template.render(template_vars=template_vars)).

    Your updated template might look like this:

    <!DOCTYPE html>
    <html>
    
    <head lang="en">
        <meta charset="UTF-8">
        <title>TITLE</title>
    </head>
    
    <body>
        <h2>Graph Goes Here</h2>
        <dl>
            {% for image in template_vars %}
            <dt>{{ image.title }}</dt>
            <dd><img title="{{ image.title }}" src="{{ image.graph }}"></dd>
            {% endfor %}
        </dl>
    </body>
    
    </html>
    

    Then, the part of your Python code that needs to be changed would look as follows:

    template_vars = [
        {"title": "TITLE", "graph": "obj.jpg"},
        {"title": "TITLE2", "graph": "obj2.jpg"},
    ]
    
    text = template.render(template_vars=template_vars)
    

    This will result in the following HTML source output:

    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>TITLE</title>
    </head>
    <body>
        <h2>Graph Goes Here</h2>
        <dl>
            <dt>TITLE</dt>
            <dd><img title="TITLE" src="obj.jpg"></dd>
            <dt>TITLE2</dt>
            <dd><img title="TITLE2" src="obj2.jpg"></dd>
        </dl>
    </body></html>