首页 文章

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

提问于
浏览
1

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

简化问题

我已经在下面列出了进一步的细节,以防万一这个比我想象的更多,但这应该是问题所需的所有信息 .

如果 do_render() 返回 <p>Hello there {{ current_user.name }}</p> ,我怎么能在模板中执行以下操作,以便获取 name 的值?

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

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

完全问题

我在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输出与模板相同;声明,表达和评论都不会被视为这样 .

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

1 回答

  • 0

    除了 {% include ... %}{% extends ... %} 之外,您在运行时添加了're not going to be able to have the template system automatically render something that',而无需进行一些自定义 .

    Jinja 2的优点在于它的API功能非常强大,您可以做很多事情,而不必觉得自己是“黑客”系统 . 要做你的第一个例子所暗示的,你只需要让函数渲染包含的模板片段并返回一个渲染的字符串 . 如果您希望使用父模板的上下文呈现模板,那么这不会自动发生,但这不是问题,因为您可以直接在模板中的函数调用中传入您需要的任何内容 .

相关问题