jinja2:我可以从表达式中渲染模板标签吗?

jinja2: Can I render template tags from an expression?

我如何 return 带有来自表达式的模板标记的文本并让 Jinja 呈现标签?看起来 Jinja 只通过一次,只是转义并转储文本,而不将其作为模板的一部分进行进一步处理(这在 99% 的情况下是正确的)。有没有办法用渲染器进行两次传递,或者先渲染我的表达式的结果并将其传递给模板?

简化问题

我在下面包含了更多详细信息,以防超出我的想象,但这应该是解决该问题所需的全部信息。

如果do_render() returns <p>Hello there {{ current_user.name }}</p>,我如何在模板中执行以下操作,以便获得name的值?

<div>
{{ do_render() }}
</div>

这呈现为 <div><p>Hello there {{ current_user.name }}</p></div>,当我想要 <div><p>Hello there Sam</p></div>

完成问题

我在 Python 2.7 中使用 Flask、Flask-Bootstrap 和 Flask-Nav。我可以自己创建导航栏,none 这很重要,但是 "autogenerated" 听起来简单多了...

Flask-Bootstrap 提供 Flask-Nav 兼容渲染器;我已将其子类化以修改我的导航栏。我试图在导航栏中添加一个登录表单,右对齐。因为 BootstrapRenderer 生成了完整的导航栏,所以我必须在结束标记之前将我的表单注入其中(或者,我可以跳过 super() 并自己完成)。

class MyRenderer(BootstrapRenderer):
    def visit_Navbar(self, node):
        """ Returns the html for a Bootstrap navigation bar. """
        root = super(MyRenderer, self).visit_Navbar(node)

        # Replace the navbar style with my custom css
        root['class'] = 'navbar navbar-mystyle'

        # Here I try injecting a login form. This is the correct position,
        # and it inserts properly; it just treats {{, }}, {%, %}
        # as nothing special.
        elem = root[0][1] # div class="navbar navbar-collapse"
        elem.add(
            dominate.util.include(
            os.path.join(
            config.app_path_root, app.template_folder, 'inc/login_form.jinja')))

        # I have also tried
        # elem.add('{% block nav_right %}{% endblock %}')
        # thinking I would use inheritance later (still my preference).

        return root

然后我用 Flask-Nav 注册渲染器,并通过将 {{ nav.main_nav.render() }} 插入我的基本模板来渲染它,我的 .html 文件继承自该模板。所有这些都有效。

我的问题是我只需要在用户未登录时使用登录表单。

login_form是:

{% if not current_user.is_authenticated() %}
<form class="navbar-form navbar-right" role="search" action="login" method="post">
<div class="form-group"><input type="text" name="username" /></div>
<div class="form-group"><input type="password" name="password" /></div>
</form>
{% else %}
<div class="navbar-right">
Welcome {{ current_user.name }} | <a href="{{ url_for('logout') }}">Logout</a>
</div>
{% endif %}

我的HTML输出与模板相同;语句、表达式和注释均不被视为此类。

其他尝试:我先生成了导航栏,然后通过 render_template('index.html', navbar=navbar) 将其传递给模板,但我遇到了同样的问题。我也试过宏。我正准备自己在基本模板中编写我的导航菜单并完成它,但现在感觉要放弃了。

除了 {% include ... %}{% extends ... %},您将无法让模板系统自动呈现在运行时添加到模板的内容,而无需进行一些自定义。

Jinja 2 的美妙之处在于它的 API 非常强大,您可以做很多事情而不必感觉像您的 "hacking" 系统。要执行您的第一个示例所暗示的操作,您只需要让函数呈现包含的模板片段和 return 呈现的字符串。如果您希望模板在父模板的上下文中呈现,那不会自动发生,但这不是问题,因为您可以直接在模板的函数调用中传递任何需要的内容。