1

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.

Natasha
  • 1,111
  • 5
  • 28
  • 66

1 Answers1

1

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>
Sébastien Lavoie
  • 877
  • 1
  • 11
  • 18
  • The solution posted works great! Thanks a lot. Could you please give some suggestions on how the template has to be modified to include two figures side by side i.e. 2 columns? – Natasha Sep 26 '22 at 03:39
  • That should be a separate question as per the Stack Overflow customs since this is more about CSS than anything else. Nevertheless, I think a good place to start would be with Flexbox. Great resources for this might include the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox) and [Flexbox Froggy](https://flexboxfroggy.com/). Else you can keep things simpler, search for keywords like these: `html two columns layout`. You would only need to edit a bit your template inside the `
    ` tag (and use some other tag instead, like `
    `).
    – Sébastien Lavoie Sep 27 '22 at 00:52