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 呈现的字符串。如果您希望模板在父模板的上下文中呈现,那不会自动发生,但这不是问题,因为您可以直接在模板的函数调用中传递任何需要的内容。
我如何 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 呈现的字符串。如果您希望模板在父模板的上下文中呈现,那不会自动发生,但这不是问题,因为您可以直接在模板的函数调用中传递任何需要的内容。