从Jinja模板调用Python函数

6
有没有办法在Jinja模板里调用一个Python函数?该函数只会把字符串years转换成一个列表。
years = years.replace('[', '')
years = years.replace(']', '')
years = years.split(',')

在下面的模板中,我该如何在years上调用它?
{% extends "base.html" %}
{% import "_macros.html" as macros %}

{% block title %}Year Results{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Year Search Results</h1>
</div>
<ul class=entries>
    {% for entry in entries %}
    <li><h3><a href="{{ url_for('main.grantinfo', applid=entry.appl_id) }}">{{ entry.appl_id }} : {{ entry.project_title }}</a></h3>
    <br>
    {% else %}
    <li><em>No entry here</em>
    {% endfor %}
</ul>

{% if pagination %}
<div class="pagination">
    {{ macros.pagination_widget(pagination, '.yearresults', years=years) }}
</div>
{% endif %}
{% endblock %}
3个回答

22

使用@app.context_processor装饰器可以在模板中调用函数。

类似于 main.py 这样的 Python 文件。

@app.context_processor
def my_utility_processor():

    def date_now(format="%d.m.%Y %H:%M:%S"):
        """ returns the formated datetime """
        return datetime.datetime.now().strftime(format)

    def name():
        """ returns bulshit """
        return "ABC Pvt. Ltd."

    return dict(date_now=date_now, company=name)

在像 footer.html 这样的 HTML 文件中

<p> Copyright {{ company() }} 2005 - {{ date_now("%Y") }} </p>

输出

Copyright ABC Pvt. Ltd. 2005 - 2015

在你的例子中,company=name 可以直接写成 company="ABC Pvt. Ltd.",然后在 footer.html 中只需要写 {{ company }}。但是如果以后需要扩展或复杂化,你的例子就非常好了。只是为了返回一些常量字符串,它不必调用函数(为了未来可能会感到困惑的读者)。 - jeromej
3
我知道这个问题标记了Flask,但Google没有。因此,应该说明这是一个特定于Flask的答案。对其他人没有帮助。 - Bruno Bronosky

10

years 似乎是一个 JSON 列表,因此请使用 json.loads 进行解析,而不是手动剥离和分割字符串。 years 似乎是从视图发送到模板的变量,因此只需在视图中处理即可。

years = json.loads(years)
# years string "[1999, 2000, 2001]"
# becomes list [1999, 2000, 2001]
# without parsing the string manually
return render_template('years.html', years=years)

如果你真的需要在模板中使用(其实你可能不需要),你可以将json.loads添加到Jinja全局变量中。

app.add_template_global(json.loads, name='json_loads')

然后像普通函数一样在模板中使用它。

{{ macros.pagination_widget(pagination, '.yearresults', years=json_loads(years)) }}

8
以下是可能的方法:
首先,在您的main.py文件中:
def myYearLister(year):
    return year.INTOLISTORWHATEVER

然后在 main.py 中的某个位置(最好在函数之后)包含以下内容,以使该函数全局可访问。

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

最后,你可以这样从你的模板中调用或使用该函数。
<div> {{ myYearLister(anything) }} </div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接