Flask - 在没有模板的情况下使用 jinja 宏

Flask - use jinja macros without a template

我有一个如下所示的 Flask 应用程序:

@app.route('/')
def index():
    headline = render_template('headline.html', headline = 'xyz') #-> return <h1>xyz</h1>
    return render_template('page.html', headline = headline) # insert headline html into a page

headline.html 是一个从宏文件 (macros.html) 导入 jinja 宏的模板。宏生成标题。

headline.html:

{% import 'macros.html' as macros %}
{{ macros.get_headline(headline) }}

macros.html:

{% macro get_headline(headline) %}
<h1>{{ healine }}</h1>
{% endmacro %}

我的问题是 - 是否可以调用宏来获得 headline 而无需调用模板 headline.html

理想情况下,我想看看

@app.route('/')
def index():
    headline = # somehow call get_headline('xyz') from macros.html
    return render_template('page.html', headline = headline) # insert headline html into a page

您可以从字符串呈现模板,而不是从文件呈现模板。所以你可以从一个字符串中调用你的宏。

from flask.templating import render_template_string

@app.route('/')
def index():
    headline = render_template_string(
        "{% import 'macros.html' as macros %}"
        "{{ macros.get_headline(headline) }}",
        headline='xyz'
    )
    return render_template('page.html', headline=headline)

(忽略 healine 而不是 macros.html 中的 headline

My question is - is it possible to call the macro to get headline without the need to call the template headline.html?

希望您了解自己的情况。我敢打赌,你最终会找到比你提议的更好的方法来做到这一点,这对我来说似乎有点倒退,但是嘿,这是学习过程的一部分!

特别是对于仅采用单个参数的简单文本转换函数,您可以从 Python 函数中获得更好的里程,您将其注册为 Environment.filters 中描述的 Jinja 过滤器 here.它的语法更少,您可以以标准方式使用 Python 您的 Jinja 模板中的相同功能,无需修改。

也就是说,我今天误入了 Jinja 模板上的 .module property。它允许您像常规 Python 函数一样从模板调用宏:

macros.html:

{% macro get_headline(headline) -%}
<h1>{{ headline }}</h1>
{%- endmacro %}

test.py:

# these imports not needed for a Flask app
from jinja2 import Environment, FileSystemLoader

# just use `app.jinja_env` for a Flask app
e = Environment(loader=FileSystemLoader('.'))
t = e.get_template('macros.html')

t.module.get_headline('Headline')
# >>> '<h1>Headline</h1>'

我相信 (?) 这可以满足您最初的要求,使用 Flask 已有的 app.jinja_env 环境,无需额外导入。