Flask cannot import enumerate? UndefinedError: 'enumerate' is undefined
Asked Answered
L

4

27

I just write this code in a HTML page.

{% for i, val in enumerate(['a', 'b', 'c']) %}
    <td>
        {{ val }}
    </td>
{% endfor %}

UndefinedError: 'enumerate' is undefined

So, Flask do not support the enumerate?

Lebensraum answered 20/11, 2014 at 9:15 Comment(0)
S
76

As Or Duan says, Jinja2 has its own language. Looks like Python but it's not Python. So the Python enumerate built-in function is not part of Jinja2 template engine. There are, however, some alternatives you can use:

If you want to enumerate the items in a list you can use the loop.index0 loop special variable:

>>> from jinja2 import Template

>>> t1 = """
... {% for val in ['a', 'b', 'c'] %}
...     <td>
...         {{ loop.index0 }} {{ val }}
...     </td>
... {% endfor %}
... """
>>> Template(t1).render()

Another option is to precalculate the enumerated version of the list:

>>> t2 = """
... {% for i, val in l %}
...     <td>
...         {{ i }} {{ val }}
...     </td>
... {% endfor %}
... """
>>> Template(t2).render(l=enumerate(['a', 'b', 'c']))

And also another one, could be even passing enumerate as a variable too:

>>> t3 = """
... {% for i, val in enumerate(['a', 'b', 'c']) %}
...     <td>
...         {{ i }} {{ val }}
...     </td>
... {% endfor %}
... """
>>> Template(t3).render(enumerate=enumerate)

Flask allows injecting variables automatically into the context of a template by means of Context Processors. So if you want enumerate built-in function to be available for all your templates, this could be a nice solution:

@app.context_processor
def inject_enumerate():
    return dict(enumerate=enumerate)

Thanks to Sean Vieira for this suggestion.

Segmental answered 20/11, 2014 at 10:1 Comment(4)
One more option is to register a context processor and expose what you want from Python inside of the Jinja environment. Nice list, by the by.Commemoration
@SeanVieira Nice solution. I added that option to the list. Hope it's what you meant.Segmental
+1 Thanks for the answer. I struggled to understand it - I needed ample time to figure out what means Template().render(something). So there is a room for improvement.Spooky
Thanks all for this solution. It's good to mention that loop.index also exist which starts at index 1 unlike loop.index0 which starts at 0.Soulless
E
6

Flask use Jinja2 to render your template, Jinja2 have a similar python syntax but it's not python.

What you can do? In your python code:

my_dict = enumerate(some_list)

Then when rendering the template send the dict to it:

render_template('page.html', my_dict=my_dict)
Ecstasy answered 20/11, 2014 at 9:27 Comment(1)
thank you very much for this. But I think in case of the enumerate, the loop.index0 can do the trick.Soulless
B
0

I never use Python in templates. I generate the HTML in a controller, put it in a variable, and have the template reference it.

In the controller

@app.route("/xxx")
def xxx():
    html = []
    for (i, val) in enumerate(["a", "b", "c"]):
        html.append(f"""<td> {i} {val}</td>""")
    cells = "\n".join(html)
    return render_template("xxx.html", cells=cells)

In the template:

<tr>
{{cells|safe}}
</tr>

Then you have always full python when you do python things, and templates do not get mixed up with Python code.

Bedlamite answered 10/8, 2022 at 8:34 Comment(0)
T
0

Jinja2 doesn't support 'enumerate' function directly. However, we can work around this limitation by creating a custom Jinja2 filter that provides enumeration functionality.

In main.py - create a custom filter function to mimic 'enumerate'.

from flask import Flask, render_template

app = Flask(__name__)

# Custom filter function to mimic enumerate
def jinja2_enumerate(iterable):
    return enumerate(iterable)

# Add the custom filter to the Jinja environment
app.jinja_env.filters['enumerate'] = jinja2_enumerate

In your template, example.html.

{% for i, val in ['a', 'b', 'c,]|enumerate %}
    <td>
        {{ val }}
    </td>

Documentation: Registering Filters - https://flask.palletsprojects.com/en/2.3.x/templating/

Trypanosomiasis answered 25/2, 2024 at 17:57 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.