Подтвердить что ты не робот

Handlebars.js в шаблонах Django

Мне нужна система шаблонов javascript, и я думаю, что handlebars.js делает отличную работу в этом случае. У меня возникают конфликты синтаксиса с шаблонами дескрипторов внутри шаблона django, потому что django пытается отобразить переменные handlebars.

Есть ли тег в шаблонах django, чтобы остановить рендеринг блока с фигурными фигурными скобками?

Что-то вроде:

{{ django_context_varable }} #works
{{% raw %}}
<script id="restaurants-tpl" type="text/x-handlebars-template">
    <ul>
    {{#restaurants}} #not rendered by django, plain text
    <li>{{name}}</li>
    {{/restaurants}}
    </ul>
</script>
{{% endraw %}}

Edit

Вероятно, я нашел этот. Он отлично работает.

Обновление

Django 1.5 поддерживает verbatim тег.

4b9b3361

Ответ 1

Есть ли тег в шаблонах django, чтобы остановить рендеринг блока с фигурными фигурными скобками?

OLD Ответ для Django 1.0-1.4: Нет, хотя можно, хотя вы могли бы поместить блок в отдельный файл и включить его без рендеринга или использования другого механизма шаблонов.

Новый ответ. Ответ выше был правильным в августе 2011 года, когда был задан вопрос и ответили. Начиная с Django 1.5 (выпущенный в феврале 2013 года, хотя альфа/бета-версии в конце 2012 года), они представили {% verbatim %} и {% endverbatim %}, которые помешают движку шаблона django обрабатывать содержимое в блоке.

Таким образом, для заданного вопроса следующее будет работать в django 1.5+ из коробки:

{{ django_context_varable }} #works
{% verbatim %}
<script id="restaurants-tpl" type="text/x-handlebars-template">
    <ul>
    {{#restaurants}} #not rendered by django, plain text
    <li>{{name}}</li>
    {{/restaurants}}
    </ul>
</script>
{% endverbatim %}

Документация по verbatim здесь. Да, это было отмечено другими ранее, но поскольку это принятый ответ, я должен указать самое простое решение.

Ответ 2

Я использую специальный тег шаблона для другой системы шаблонов js, здесь: https://gist.github.com/629508

Использовать в шаблоне:

{% load mytags %}
{% verbatim %}
  {{ This won't be touched by {% django %} template system }}
{% endverbatim %}

Изменить: Этот настраиваемый тег шаблона больше не нужен, так как язык шаблона Django теперь поддерживает тег шаблона {% verbatim%}.

Ответ 3

для более глубокой интеграции между рулями и Django (включая опциональную предварительную компиляцию на лету), проверьте мой проект на https://bitbucket.org/chrisv/django-handlebars/

В основном он работает следующим образом:

  • создать шаблон HB в

    appdirectory/hbtemplates/myapp/template.html
    

    (как и шаблон Django)

  • в вашем приложении, используйте

    {% handlebars myapp %} 
    

    тег шаблона и шаблон вывода так:

    Handlebars.templates["myapp.template.html"]({context:"value"});
    

Ответ 4

Я написал очень маленькое приложение django: django-templatetag-handlebars именно для этой цели.

{% load templatetag_handlebars %}

{% tplhandlebars "tpl-infos" %}
    {{total}} {% trans "result(s)." %}
    <p>{% trans "Min" %}: {{min}}</p>
    <p>{% trans "Max" %}: {{max}}</p>
{% endtplhandlebars %}

Отредактируйте свой блок, как обычно, с помощью Handlebars.js API:

var properties = {
    total: 10,
    min: 5,
    max: 4
};

var template = Handlebars.compile($('#tpl-infos').html()),
    rendered = template(properties);

Я написал это в тот день, когда @chrisv опубликовал свой пакет с учетом подхода KISS. В основном это основано на Miguel Araujo gist: https://gist.github.com/893408.

Ответ 5

Почему бы не использовать jinja2 вместо этого? ИМО, они оба элегантны в использовании. Вот отличная статья об этом: Использование Jinja2 с Django

Ответ 6

Система шаблонов Django не поддерживает экранирование блоков одновременно. Было бы легко обойти это, если бы не тот факт, что при обработке шаблонов токенизатор не содержит точной информации о том, как выглядели маркеры, прежде чем они получили токены.

Я использовал следующую работу, которая является уродливой, но (вроде) работает. Используйте разные разделители тегов в ваших шаблонах и тег шаблона django, который переводит их обратно на то, что вы действительно хотите:

@register.tag(name="jstemplate")
def do_jstemplate(parser, token):
    while self.tokens:
        token = self.next_token()
        if token.token_type == TOKEN_BLOCK and token.contents == endtag:
            return
    self.unclosed_block_tag([endtag])
    nodelist = parser.parse( ('endjstemplate',) )
    parser.delete_first_token()
    s = token.split_contents()
    tmpl_id = Variable( s[1] ) if (len(s) == 2 and s[1]) else ''
    return JsTemplateNode( nodelist, tmpl_id )

class JsTemplateNode(template.Node):
    def __init__(self, nodelist, tmpl_id=''):
        self.tmpl_id = tmpl_id
        self.nodelist = nodelist
    def render(self, context):
        content = self.nodelist.render(context)
        return u'<script id="%s" type="text/x-handlebars-template">%s</script>' % (
                self.tmpl_id.resolve(context),
                re.sub( ur'{\$(.*?)\$}', u'{{\\1}}', content ), )

Для бонусных очков вы можете использовать шаблоны Django в своих шаблонах... который, вероятно, приготовит ваш мозг, пытаясь распутать позже:

{% jstemplate "restaurants-tpl" %}
{$#restaurants$}
<div id="<$name$<" class="{$type$}">
    <ul class="info">
        {$#if info/price_range$}<li><em>{{ trans "Price Range" }}:</em> {$info/price_range$}</li>{$/if$}
        {$#if info/awards$}<li><em>{{ trans "Awards" }}:</em> {$info/awards$}{$/if$}
    </ul>
    <div class="options">
        <button>{% trans "Reservation" %}</button>
    </div>
</div>
{$/restaurants$}
{% jstemplate %}

Ответ 7

На самом деле я написал собственный фильтр шаблонов, который выглядит следующим образом:

from django import template
register = template.Library()
def handlebars(value):
    return '{{%s}}' % value
register.filter('handlebars', handlebars)

и используйте его в шаблоне следующим образом:

{{"this.is.a.handlebars.variable"|handlebars}}

Это самая простая вещь, о которой я мог думать. Вам просто нужно указать имя переменной handlebars в кавычках. Я сожалею, что у меня не было этой идеи, прежде чем я боролся с ssi. Он также работает с ключевыми словами:

{{"#each items"|handlebars}}

Ответ 8

Сначала скомпилируйте рули!

Из описательная документация с предварительным скомпилированием ручек:

В дополнение к уменьшению размера загрузки устранение компиляции на стороне клиента значительно ускорит время загрузки, поскольку компиляция является самой дорогой частью Handlebars.

Вы можете скомпилировать шаблоны в своей среде сборки, используя модуль npm для руд или интегрировать его с помощью инструмента построения, такого как gulp, с gulp-handlebars.

После компиляции ваши шаблоны дескрипторов могут обслуживаться как статические ресурсы и вообще обходить сторону сервера. Это также облегчает кэширование:)

Типичное использование будет выглядеть так:

<div id="restaurants-tpl">
    Waiting for content...
</div>

<script src="{% static 'js/handlebars.runtime.js' %}"></script>
<script src="{% static 'js/templates.js' %}"></script>
<script>
    // Let django render this as a json string
    properties = {{ properties }};

    // Use Handlebars compiled template imported above
    rendered_html = Handlebars.templates["restaurants-tpl"](properties);

    // Set element content 
    document.getElementById("restaurants-tpl").innerHTLM = rendered_html;
</script>