轻松逃脱Django模板变量

时间:2010-02-02 14:56:51

标签: django django-templates

对于一个新项目,我们正在编写关于 Django模板系统的文档。我们也将Django用于文档项目本身,因此Django会在示例代码中获取所有示例变量并尝试渲染它们。我们发现解决这个问题的唯一方法是使用{% templatetag %},但这会使我们的代码真的难以理解。有没有办法让Django忽略特定部分中的所有模板变量?

6 个答案:

答案 0 :(得分:15)

Django 1.5使用verbatim模板标记解决了这个问题。它也适用于当前的Django版本。

{% verbatim myblock %}
    Avoid template rendering via the {% verbatim %}{% endverbatim %} block.
{% endverbatim myblock %}

答案 1 :(得分:7)

由于Django模板词法分析器的限制(就像是一个kludgy hack),这是不可能的。但是,如果您愿意将示例代码放在单独的文件中,则可以使用ssi标记:

{% ssi /path/to/my/code/examples/example01.html %}

它不会解析文件,只是逐字地包含它。但是,这也有局限性,因为你不能在include路径中使用变量(即如果你移动模板位置,你必须重写或至少找到并替换你的模板文件),你必须把包含您/path/to/my/code/examples的{​​{1}}设置中的路径(即ALLOWED_INCLUDE_ROOTS)。 (见http://docs.djangoproject.com/en/dev/ref/templates/builtins/#ssi。)

答案 2 :(得分:3)

一种可能的解决方案是像往常一样编写模板(使用{{ x }}),但将它们保存为.txt(或任何其他所需的扩展名)。编写运行在这些文件上的脚本,并通过执行与templatetag相反的操作(将{{替换为{% templatetag openvariable %}等)自动为您创建.html。确保在更新模板后运行代码。

答案 3 :(得分:3)

我通过添加一个“include_raw”模板标记来解决这个问题,该标记的行为类似于内置的“include”标记,但只是不解析或处理传递给它的文件。我在App Engine下运行Django 1.2。

创建标签模块(tags.py):

from django.template import loader
from google.appengine.ext.webapp import template

register = template.create_template_register()

@register.simple_tag
def include_raw(path):
  return loader.find_template(path)[0]

注册:

from google.appengine.ext.webapp import template

template.register_template_library("tags")

使用它:

{% include_raw "this-will-be-included-verbatim.html" %}

答案 4 :(得分:3)

如果您的来源是HTML,最简单的解决方案是将“{”和“}”替换为各自的HTML实体:

{变为{

}变为}

示例:

<code>
To include some other file, you can use the &#123;% include %&#125; template tag. 
To include a variable, use &#123;%&#123;% varname &#125;%&#125;%.
</code>

答案 5 :(得分:0)

这是解决Djano 1.4问题的优雅方法。这是一个Django自定义标签。 只需创建一个包含以下代码的模块verbatim_templatetag.py:

"""
jQuery templates use constructs like:

    {{if condition}} print something{{/if}}

This, of course, completely screws up Django templates,
because Django thinks {{ and }} mean something.

Wrap {% verbatim %} and {% endverbatim %} around those
blocks of jQuery templates and this will try its best
to output the contents with no changes.
"""

from django import template

register = template.Library()


class VerbatimNode(template.Node):

    def __init__(self, text):
        self.text = text

    def render(self, context):
        return self.text


@register.tag
def verbatim(parser, token):
    text = []
    while 1:
        token = parser.tokens.pop(0)
        if token.contents == 'endverbatim':
            break
        if token.token_type == template.TOKEN_VAR:
            text.append('{{')
        elif token.token_type == template.TOKEN_BLOCK:
            text.append('{%')
        text.append(token.contents)
        if token.token_type == template.TOKEN_VAR:
            text.append('}}')
        elif token.token_type == template.TOKEN_BLOCK:
            text.append('%}')
    return VerbatimNode(''.join(text))

然后在您的模板中:{%load verbatim_templatetag%}

{%verbatim%}和{%endverbatim%}之间的所有内容都不会被解析。

来自https://gist.github.com/ericflo/629508的代码