Moustacheは初めてです。
多くのテンプレート言語(例:Django/Jinja)では、「親」テンプレートを次のように拡張できます。
<html><head></head>
<body>
{% block content %}{% endblock %}
</body>
</html>
{% extends "base.html" %}
{% block content %}<h1>Foobar!</h1>{% endblock %}
<html><head></head>
<body>
<h1>Foobar!</h1>
</body>
</html>
Moustacheのpartialsを知っています(例:{{>content}}
)、しかしそれらはちょうどincludesのようです。
Moustache用のテンプレート拡張機能はありますか?または、それに失敗すると、includesをテンプレート拡張の同等物に効果的に変える設計パターンが少なくともあります。
私は最近、マコのバックグラウンドから来たことを除いて、同じボートに乗っていました。
Moustacheはテンプレートの拡張/継承を許可しませんが、私が知っている利用可能なオプションがいくつかあります。
パーシャルを使用できます:
{{>header}}
Hello {{name}}
{{>footer}}
他のページから継承する必要がある各テンプレートのコンテキストに、テンプレートの前処理関数を挿入できます。
{{#extendBase}}
Hello {{name}}
{{/extendBase}}
ハッシュ:
{
"name": "Walden",
"extendBase": function() {
return function(text) {
return "<html><head></head>" + render(text) + "</body></html>"
}
}
}
目的のHTMLをプリペンドして、コントローラーの関連ページに追加します。
レイアウトテンプレートalaを使用します。
{{>header}}
{{{body}}}
{{>footer}}
コントローラーで本体をレンダリングし、body
という名前の変数としてレイアウトテンプレートに渡します。
テンプレートをロードするコードに、テンプレート継承、事前口ひげを実装します。
ただし、エスケープされていないHTMLをどこにも表示したくないため、トリプルヒゲを使用しません。
他の誰かがこの問題に対するより良い解決策を持っているなら、私はこれらの方向のいずれにもまだ思い切っていないので、私もそれを聞きたいです。
ここで、Mustacheの仕様にこれを提案しました。
https://github.com/mustache/spec/issues/38
現在、mustache.Java、hogan.js、phly_mustacheはテンプレートの継承をサポートしています。
口ひげphpでは、バージョン2.7.0以降、テンプレートの継承がサポートされています。
https://github.com/bobthecow/mustache.php/wiki/BLOCKS-pragma
ファイルMustache/Engine.phpから現在のバージョンを把握し、以下を含む行を検索できます。
class Mustache_Engine
{
const VERSION = '2.8.0';
...
Moustacheはテンプレートの拡張を行いません。
テンプレートの拡張が本当に必要な場合は、選択した言語/フレームワークに対して、この機能で構築されたライブラリ目的を使用することができます。
参考までに、Node.js/Expressを使用しているため、おそらく https://github.com/fat/stache を使用することになります。
HTMLを含む変数を使用できます。 {{{variable}}}
のような「トリプルヒゲ」はエスケープされていないHTMLを返します。テンプレートの拡張機能とまったく同じではありませんが、frontpage-content.htmlをレンダリングし、その出力をbase.htmlに渡されるcontent
変数に入れることができます。
(私は-contentをfrontpage.htmlファイル名に追加しました。このような命名パターンはファイル名を管理しやすくすることを期待しています。)
私はこれをPython(私はMakoの作成者です)で遊んでいます)、セクションをキャプチャする動的なコンテキストに追加することは正しいことをしているようですが、これをさらにテストする必要があります。
基本的には、「<」プレフィックスが「このテンプレートから継承する」ことを示すラムダを使用しています( https://github.com/mustache/spec/issues/38 で説明されている構文と同様)。 「$」プレフィックスは、「これは継承されたセクションです」を示します。
import pystache
class NameSpace(object):
def __init__(self, renderer, vars_={}):
self.renderer = renderer
self._content = {}
self.vars = vars_
def add_content(self, name, value):
self._content[name] = value
def __getattr__(self, key):
if key in self.vars:
# regular symbol in the vars dictionary
return self.vars[key]
Elif key.startswith("<"):
# an "inherit from this template" directive
name = key[1:]
return inheritor(self, name)
Elif key.startswith("$"):
# a "here's a replaceable section" directive
name = key[1:]
if name in self._content:
# if we have this section collected, return the rendered
# version
return sub_renderer(self, name)
else:
# else render it here and collect it
return collector(self, name)
else:
# unknown key.
raise AttributeError(key)
def sub_renderer(namespace, key):
def go():
def render(nested):
return namespace._content[key]
return render
return go
def collector(namespace, key):
def go():
def render(nested):
content = namespace.renderer.render(nested, namespace)
namespace.add_content(key, content)
return content
return render
return go
def inheritor(namespace, name):
def go():
def render(nested):
namespace.renderer.render(nested, namespace)
return namespace.renderer.render_name(name, namespace)
return render
return go
ここにいくつかのテンプレートがあります。 base.mustache:
<html>
{{#$header}}
default header
{{/$header}}
{{#$body}}
default body
{{/$body}}
{{#$footer}}
default footer, using {{local key}}
{{/$footer}}
</html>
hello.mustache:
{{#<base}}
{{#$header}}
new header
{{/$header}}
{{#$body}}
new body, with {{local key}}
{{/$body}}
{{/<base}}
そして、3レベルの深さで遊ぶには、subhello.mustache:
{{#<hello}}
{{#$footer}}
im some new footer
{{/$footer}}
{{/<hello}}
このようなhello.mustacheのレンダリング:
renderer = pystache.Renderer(search_dirs=["./templates/"])
print renderer.render_name("hello",
NameSpace(renderer, {"local key": "some local key"}))
出力:
<html>
new header
new body, with some local key
default footer, using some local key
</html>
Subhello.mustacheのレンダリング:
print renderer.render_name("subhello",
NameSpace(renderer, {"local key": "some local key"}))
出力:
<html>
new header
new body, with some local key
im some new footer
</html>
私はこれを20分で書きましたが、過去にhandlebars.jsを少しだけ使用し、今は初めてpystacheを使用したので、「口ひげ」のアイデア全体はまだ深くありません。しかし、これはうまくいくようですか?
サーバーサイドのみのコードに満足している場合は、 Nunは「テンプレートのオーバーライド」機能を介して機能を拡張する口ひげのようなテンプレートシステムです -Djangoでモデル化されています。ただし、動作している間は、作成者によって保守されなくなります。
Node.jsでは、 express-handlebars または hogan-express を使用して、Inna Moustacheテンプレートをレイアウトできますが、設定方法は異なります。テンプレート自体のレイアウト、レイアウトはアプリコードに登録されます。