来自上下文的嵌套模板标记

时间:2011-12-10 23:29:18

标签: django django-templates django-views

我有一个案例,我需要在上下文(视图)中设置一个带有另一个嵌套模板变量标签的模板变量,并使用django模板机制来解析标签和嵌套标签。

在视图中我有:

page['title'] = 'This is a test title for page {{ page.foo }}'
page['foo']   = 'Test'
...
render_to_response('x.html', {'page':page})

在模板中我有:

<html>
....
<title>{{page.title}}</title>
...</html>

如何在渲染时让page.title也解析嵌入的page.foo标记?

2 个答案:

答案 0 :(得分:1)

我不知道有什么方法可以做到这一点,如果没有默认实现,也不会感到惊讶,因为Django将无法一次性渲染所有内容......

以下是一些有点接近的事情,也许有帮助。

最简单:只需使用Python %s在您的视图中执行此操作

page['title'] = 'This is a test title for page %s' % page['foo']

如果你想使用Django渲染:

page['title'] = Template(page['title']).render(Context({'page': page, }))

在您的视图中,这会将This is a test title for page {{ page.foo }}page呈现为上下文。

如果您只使用默认上下文中的内容,则可以编写一个过滤器,使用该上下文呈现当前字符串,如{{ page.title|render }}。但是我不知道从模板中获取整个上下文的方法,所以这只适用于防御上下文值。

编辑:找到另一种方式,会做出新的答案。

答案 1 :(得分:1)

您可以创建一个模板标记,用于在当前上下文中呈现变量。有关自定义模板标记的一般信息,请参阅https://docs.djangoproject.com/en/dev/howto/custom-template-tags/

结果:

{% load renderme %}
{% renderme page.title %}

成为(针对您提供的上下文):

This is a test title for page Test 

模板标记代码(您必须改进输入检查,最值得注意的是它还不接受直接传递字符串):

from django import template
from django.template.context import Context
from django.template.base import Template

class RenderNode(template.Node):

    def __init__(self, template_string_name = ''):
        self.template_string_name = template_string_name

    def render(self, context):
        ''' If a variable is passed, it is found as string, so first we use render to convert that
            variable to a string, and then we render that string. '''
        self.template_string = Template('{{ %s }}' % self.template_string_name).render(context)
        return Template(self.template_string).render(context)

def render_me(parser, token):
    try:
        tag_name, template_string_name = token.split_contents()
    except Exception:
        raise template.TemplateSyntaxError('Syntax for renderme tag is wrong.')
    return RenderNode(template_string_name)

register = template.Library()
register.tag('renderme', render_me)
你去吧!您将需要使用标记而不是普通变量或过滤器,但它会执行您所描述的内容。

相关问题