【问题标题】:jinja2: Can I render template tags from an expression?jinja2:我可以从表达式中渲染模板标签吗?
【发布时间】:2015-12-02 11:36:49
【问题描述】:

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

简化问题

我在下面提供了更多详细信息,以防万一这比我想象的要多,但这应该是解决问题所需的所有信息。

如果do_render()返回<p>Hello there {{ current_user.name }}</p>,如何在模板中进行如下操作,得到name的值?

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

当我想要&lt;div&gt;&lt;p&gt;Hello there Sam&lt;/p&gt;&lt;/div&gt; 时,它呈现为&lt;div&gt;&lt;p&gt;Hello there {{ current_user.name }}&lt;/p&gt;&lt;/div&gt;

完成问题

我在 Python 2.7 中使用 Flask、Flask-Bootstrap 和 Flask-Nav。我可以自己创建导航栏,这些都不重要,但是“自动生成”听起来要简单得多...

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 输出与模板相同;语句、表达式和 cmets 都不会被这样对待。

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

【问题讨论】:

    标签: python flask jinja2


    【解决方案1】:

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

    Jinja 2 的美妙之处在于它的 API 非常强大,您可以做很多事情而不必感觉像“入侵”系统。要执行第一个示例所暗示的内容,您只需让函数渲染包含的模板 sn-p snd 返回渲染的字符串。如果您希望模板与父模板的上下文一起呈现,这不会自动发生,但这不是问题,因为您可以直接在模板中的函数调用中传递您需要的任何内容。

    【讨论】:

    • 比我做的简单多了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2017-03-01
    • 2020-11-24
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    • 2012-03-30
    • 2020-03-14
    • 2017-10-04
    相关资源
    最近更新 更多