web-dev-qa-db-ja.com

DjangoテンプレートのHandlebars.js

Javascriptテンプレートシステムが必要です。この場合、handlebars.jsは優れた仕事をしていると思います。 Djangoがハンドルバー変数をレンダリングしようとするため、Djangoテンプレート内のハンドルバーテンプレートと構文が競合しています。

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 %}}

編集

おそらく私は this を見つけました。それはうまくいきます。

更新

Django 1.5は verbatim タグをネイティブにサポートします。

31
tsiokos

Djangoテンプレートに中括弧でブロックのレンダリングを停止するタグはありますか?

Django 1.0-1.4の古い回答: いいえ、 ただし、ブロックを別のファイルに入れて、レンダリングせずに含めるか、別のテンプレートエンジンを使用することはできます。

新しい回答:上記の回答は2011年8月に質問と回答があったときに正解でした。 Django 1.5(2013年2月にリリース、ただし2012年後半にアルファ/ベータバージョン)から、Djangoを防ぐ{% verbatim %}{% endverbatim %}が導入されました。テンプレートエンジンは、ブロック内のコンテンツを処理しません。

したがって、尋ねられた質問に対して、以下はDjango1.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 %}

逐語的はここにあります に関するドキュメント。はい、これは以前に他の人によって指摘されましたが、これは受け入れられた答えなので、最も簡単な解決策をリストする必要があります。

20
dr jimbob

別のjsテンプレートシステム用のカスタムテンプレートタグを使用しています: https://Gist.github.com/629508

テンプレートでの使用:

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

編集:Djangoのテンプレート言語が{%逐語的%}テンプレートタグをサポートするようになったため、このカスタムテンプレートタグは不要になりました。

30
rych

ハンドルバーとDjango(オプションのオンザフライプリコンパイルを含む)のより深い統合については、 https://bitbucket.org/chrisv/Django-handlebars/)で私のプロジェクトをチェックしてください。

基本的には次のように機能します。

  1. 下にHBテンプレートを作成します

    appdirectory/hbtemplates/myapp/template.html
    

    (Djangoテンプレートのように)

  2. アプリで、

    {% handlebars myapp %} 
    

    テンプレートタグとレンダリングテンプレートは次のようになります。

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

私は非常に小さな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 AP​​Iを使用して、通常どおりブロックをレンダリングします。

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

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

@chrisvがパッケージを公開した日に、KISSアプローチを念頭に置いて書きました。これは、主にMiguel Araujoの要点に基づいています: https://Gist.github.com/ 893408

3
leplatrem

最初にハンドルバーをコンパイルしてください!

From ドキュメントをプリコンパイルするハンドルバー

ダウンロードサイズを削減することに加えて、コンパイルはハンドルバーの最も高価な部分であるため、クライアント側のコンパイルを排除すると、起動時間が大幅に短縮されます。

handlebars npm module を使用してビルド環境でテンプレートをコンパイルするか、 gulp-handlebars を使用してgulpなどのビルドツールと統合することができます。

コンパイル後、ハンドルバーテンプレートを静的リソースとして提供し、サーバー側のレンダリングを完全にバイパスできます。キャッシュも簡単になります:)

一般的な使用法は次のようになります。

<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>
2

実際、私は次のようなカスタムテンプレートフィルターを作成しました。

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

次のようなテンプレートで使用します。

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

それは私が考えることができる最も簡単なことです。ハンドルバーの変数名を引用符で囲む必要があります。 ssiに苦労する前に、このアイデアを思いつかなかったことを後悔しています。キーワードでも機能します。

{{"#each items"|handlebars}}
1
Luke Hall

代わりに jinja2 を使用してみませんか? IMO、どちらもエレガントに使用できます。これについての優れた記事があります: DjangoでJinja2を使用する

1
jpanganiban

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 %}
1
Borgar