3

I am sending one list of list to my HTML page, using flask jinja2 template. I want to check:- is item in list is of type str or not ?. But getting an exception of

jinja2.exceptions.UndefinedError: 'isinstance' is undefined

Code is as below:-

{% for i in req%}

    <tr>
        <th scope="row">{{loop.index}}</th>
        <td>{{i[1]}}</td>
        <td>{{i[24]}}</td>
        <td>{{i[49]}}</td>
        <td>{{i[53]}}</td>
        {% if isinstance(i[86], str) %}
            {% for j in i[86].split(",") %}
                <ol>
                    <li>{{i[86]}}</li>
                </ol>
            {% endfor %}
        {% else %}
            <td>{{i[86]}}</td>
        {% endif %}

    </tr>

    {% endfor %}

I am able to use split(",") function and Want to use isinstance() or str() of python in jinja 2 template.

Nitin Prakash
  • 328
  • 3
  • 15
raviraj
  • 335
  • 4
  • 19
  • Even though it looks like Python, it's actually Jinja2 syntax and you can only use one of the builtin [tests](https://jinja.palletsprojects.com/en/2.11.x/templates/#list-of-builtin-tests) or [functions](https://jinja.palletsprojects.com/en/2.11.x/templates/#list-of-global-functions). Anything not in those lists you'll need to [define](https://jinja.palletsprojects.com/en/2.11.x/api/#custom-tests) [yourself](https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.Environment.globals). – deceze Jun 03 '20 at 08:09
  • To add upon @deceze's comment, you can also register your own custom Jinja2 template filters using Flask: https://flask.palletsprojects.com/en/1.1.x/templating/#registering-filters – vremes Jun 03 '20 at 09:09

2 Answers2

5

The language in the jinja template is not actually python, it's python like looking, it means python built-ins are not present. To make python built-ins present in every template, at startup, add any required built-ins to the globals parameter when building the jinja2.Environment. Something like below:

app.jinja_env.globals.update(isinstance=isinstance)

or

import jinja2
env = jinja2.Environment()
env.globals.update(isinstance:isinstance)
ngShravil.py
  • 4,742
  • 3
  • 18
  • 30
  • 'app.jinja_env.globals.update(isinstance=isinstance)' worked for me. Can I register more methods over there like 'app.jinja_env.globals.update(isinstance=isinstance, sorted = soreted)'. Got syntax error' env.globals.update(isinstance:isinstance)' for next solution. – raviraj Jun 05 '20 at 11:17
  • Correct me if I am wrong, by `soreted` you mean `sorted`? Is this a typo? – ngShravil.py Jun 05 '20 at 13:22
  • You might run into the followup problem of the need to import the type to avoid TypeError: isinstance() arg 2 must be a type or tuple of types see https://stackoverflow.com/questions/4828406/import-a-python-module-into-a-jinja-template – Wolfgang Fahl Jan 04 '21 at 08:29
0

Another option is using a Flask context processor. For example, from the Flask docs, here is a context processor that makes a format_price function available in all templates in the application:

app = Flask(__name__)

@app.context_processor
def utility_processor():
    def format_price(amount, currency="€"):
        return f"{amount:.2f}{currency}"
    return dict(format_price=format_price)

The idea is that you decorate a function with @app.context_processor and then the dictionary it returns in automagically merged into the Jinja context for all templates.

Note that this can even be used to add entire modules to the template context.

ntc2
  • 11,203
  • 7
  • 53
  • 70