首先,Jinja2 支持macros
,它可以让你在模板之间共享功能:
{# helpers.jinja #}
{% macro generate_select(itrbl) %}
<select{{kwargs|xmlattrs}}>
{% for item in itrbl %}
<option value="{{item.value}}">{{item.text}}</option>
{% endfor %}
</select>
{% endmacro %}
{# page1.jinja #}
{% import "helpers.jinja" as helpers %}
{{ helpers.generate_select(data, name="my_data_field") }}
对于更复杂的功能(A / B 测试,根据用户帐户启用的功能加载不同的功能等)extends
,include
, 和import
可以采用可变值:
{# A custom template with a *lot* of hooks #}
{% extends base_template %}
{% import custom_functionality_provider as provider %}
{% block common_name %}
{% if features.feature_x %}
{% include feature_x_include %}
{% endif %}
{{ provider.operation() }}
{% endblock common_name %}
@app.route("/some-route")
def some_route():
# Of course, in real life you would determine these values
# on the basis of user / condition lookups, rather than
# hardcoding values in your render_template call
render_template("custom.jinja", base_template="AB/A/base.jinja",
custom_functionality_provider="macros/lowcostplan.jinja",
feature_x_include="AB/A/features/feature_x.jinja",
features=some_features_object)
最后,您可以将返回字符串的可调用对象传递给任何 Jinja 模板,从而获得 Python 的全部功能:
def custom_implimentation_a(**context_args):
return render_template("template_a.jinja", **context_args)
def custom_implimentation_b(**context_args):
return render_template("template_b.jinja", **context_args)
@app.route("/some-route")
def some_route():
if condition:
provider = custom_implimentation_a # Note, no parenthesis
else:
provider = custom_implimentation_b
return render_template("some_page.jinja", provider=provider)