简体   繁体   English

Jinja2 模板中的“eval”语句

[英]"eval" statement in Jinja2 template

I'm trying to convert some old Smarty templates to Jinja2.我正在尝试将一些旧的 Smarty 模板转换为 Jinja2。

Smarty uses an eval statement in the templates to render a templated string from the current context. Smarty 在模板中使用eval语句从当前上下文中呈现模板化字符串。

Is there an eval equivalent in Jinja2? Jinja2 中是否有等效的eval Or what is a good workaround for this case?或者对于这种情况有什么好的解决方法?

Use the @jinja2.contextfilter decorator to make a Custom Filter for rendering variables:使用@jinja2.contextfilter装饰器为渲染变量制作自定义过滤器

from flask import render_template_string
from jinja2 import contextfilter
from markupsafe import Markup


@contextfilter
def dangerous_render(context, value):
    Markup(render_template_string(value, **context)).format()

Then in your template.html file:然后在你的 template.html 文件中:

{{ myvar|dangerous_render }}

I was looking for a similar eval use case and bumped into a different stack overflow post.我正在寻找一个类似的 eval 用例并碰到了一个不同的堆栈溢出帖子。

This worked for me这对我有用

routes.py路线.py

def index():
    html = "<b>actual eval string</b>"
    return render_template('index.html', html_str = html)

index.html index.html

<html>
    <head>
        <title>eval jinja</title>
    </head>
    <body>
        {{ html_str | safe }}
    </body>
</html>

Reference : Passing HTML to template using Flask/Jinja2参考使用 Flask/Jinja2 将 HTML 传递给模板

If you are using jinja version 3.0, contextfilter has deprecated and removed in Jinja 3.1.如果您使用的是 jinja 3.0 版,contextfilter 已在 Jinja 3.1 中弃用和删除。 Use pass_context() instead.请改用 pass_context() 。 Refer here for more details pertaining this.有关更多详细信息, 请参阅此处

from jinja2 import pass_context, Template
from markupsafe import Markup


@pass_context
def foo(context, value):
    return Markup(Template(value).render(context)).render()

then in your template然后在你的模板中

 {{ myvar|foo }}

Based on the answers from Alan Hamlett and Hilario Nengare, I implemented the following "eval" filter for Jinja2 (>=3.0).根据 Alan Hamlett 和 Hilario Nengare 的回答,我为 Jinja2 (>=3.0) 实施了以下“eval”过滤器。 I found that the case of undefined input should also be handled, plus I added the ability to specify additional variables as input for the expression:我发现还应该处理未定义输入的情况,另外我还添加了指定额外变量作为表达式输入的功能:

import jinja2

@jinja2.pass_context
def filter_eval(context, input, **vars):
    if input == jinja2.Undefined:
        return input
    return jinja2.Template(input).render(context, **vars)

Usage, when adding filter_eval() as filter "eval":用法,当添加 filter_eval() 作为过滤器“eval”时:

  • Template source:模板来源:

     {% set rack_str = 'Rack {{ rack }}' %} {{ rack_str | eval(rack='A') }}
  • Rendered template:渲染模板:

     Rack A

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM