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 тег.
Ответы
Ответ 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>