Простой способ избежать переменных шаблона Django

Для нового проекта мы пишем документацию о системе шаблонов Django. Мы также используем Django для самого проекта документации, поэтому Django выбирает все переменные нашего примера в примере кода и пытается их отобразить. Единственный способ обойти это - использовать {% templatetag%}, но это делает наш код действительно нечитаемым. Есть ли способ заставить Django игнорировать все переменные шаблона в определенном разделе?

6 ответов

Решение

Из-за ограничений в лексере шаблонов Django (например, хакерский взлом) это невозможно. Однако, если вы хотите поместить пример кода в отдельные файлы, вы можете использовать ssi тег:

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

И он не будет анализировать файл, просто включить его дословно. Однако это также имеет ограничения, заключающиеся в том, что вы не можете использовать переменные в пути включения (т. Е. Если вы перемещаете расположения шаблонов, вы должны перезаписать или, по крайней мере, найти и заменить файлы шаблонов), и вы должны поместить включение путь (то есть /path/to/my/code/examples) в ALLOWED_INCLUDE_ROOTS установка в вашем settings.py, (См. http://docs.djangoproject.com/en/dev/ref/templates/builtins/.)

Django 1.5 решает эту проблему с помощью тега дословного шаблона. Он также отлично работает с текущими версиями Django.

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

Я решил эту проблему, добавив тег шаблона "include_raw", который ведет себя как встроенный тег "include", но просто не анализирует и не обрабатывает переданный ему файл. Я использую Django 1.2 под App Engine.

Создайте модуль тегов (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" %}

Если вашим источником является 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>

Возможное решение - написать шаблоны как обычно (с {{ x }}), но сохраните их как.txt (или любое другое расширение, которое вы хотите). Напишите сценарий, который запускает эти файлы, и автоматически создает для вас файл.html, выполнив обратную процедуру для тега шаблона (заменив {{ с {% templatetag openvariable %}так далее). Убедитесь, что код запускается после обновления шаблонов.

Вот элегантный способ решить проблему для 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

Другие вопросы по тегам