Я сейчас играю с этим в Python (обратите внимание, я создатель Mako), добавляя в динамический контекст, который захватывает разделы, похоже, правильную вещь, хотя мне нужно проверить этомного больше.
В основном мы используем лямбда-выражения, где префикс «<» указывает «наследовать от этого шаблона» (аналогично синтаксису, обсуждаемому в <a href="https://github.com/mustache/spec/issues/38" rel="nofollow">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}}
, а затем игратьс тремя уровнями глубины, 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"}))
output:
<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"}))
output:
<html>
new header
new body, with some local key
im some new footer
</html>
Я только написал это за двадцать минут, и я лишь немного использовал handlebars.js в прошлом и впервые использовал pystacheтеперь, так что вся идея "усов" еще не глубока для меня. Но, похоже, это работает?