Могут ли шаблоны Mustache делать расширение шаблона?
Я новичок в Усы.
Многие языки шаблонов (например, Django/ Jinja) позволят вам продлить "родительский" шаблон, например...
base.html
<html><head></head>
<body>
{% block content %}{% endblock %}
</body>
</html>
frontpage.html
{% extends "base.html" %}
{% block content %}<h1>Foobar!</h1>{% endblock %}
rendered frontpage.html
<html><head></head>
<body>
<h1>Foobar!</h1>
</body>
</html>
Я знаю частичные части Усы (например, {{>content}}
), но они, кажется, просто включают.
Существует ли расширение шаблона для Усы? Или, в противном случае, существует, по крайней мере, некоторый шаблон проектирования, который эффективно включается, включает в себя эквиваленты расширения шаблонов.
Ответы
Ответ 1
Недавно я оказался в одной лодке, за исключением того, что я пришел с фона мако.
Усы не допускают расширение/наследование шаблона, но есть несколько доступных вам вариантов. Я не знаю, как это сделать.
-
Вы можете использовать partials:
{{>header}}
Hello {{name}}
{{>footer}}
-
Вы могли бы вставлять шаблонные функции предварительной обработки в контекст для каждого шаблона, который должен наследовать от какой-либо другой страницы:
{{#extendBase}}
Hello {{name}}
{{/extendBase}}
Hash:
{
"name": "Walden",
"extendBase": function() {
return function(text) {
return "<html><head></head>" + render(text) + "</body></html>"
}
}
}
-
Подготовьте и добавьте желаемый HTML на соответствующие страницы вашего контроллера.
-
У вас есть шаблон макета:
{{>header}}
{{{body}}}
{{>footer}}
И визуализируйте тело в контроллере, передав его шаблону макета как переменную с именем body
.
-
Внедрить наследование шаблонов, предварительные усы, в свой код, который загружает шаблоны.
Я бы, однако, не использовал тройные усы, потому что я не хочу, чтобы unescaped HTML появлялся в любом месте, это слишком рискованно, на мой взгляд.
Если у кого-то есть лучшее решение этой проблемы, я тоже хотел бы услышать это, так как я еще не сделал ни одного погружения в любом из этих направлений.
Ответ 2
Я предложил это для спецификации для Усы:
https://github.com/mustache/spec/issues/38
В настоящее время mustache.java, hogan.js и phly_mustache поддерживают наследование шаблонов.
Ответ 3
Вы можете использовать переменные, содержащие HTML. "Тройные усы", такие как {{{variable}}}
, возвращают неэкранированный HTML. Это не совсем то же самое, что и расширение шаблонов, но вы можете отобразить frontpage-content.html, а затем поместить его вывод в переменную content
, которая будет передана в base.html.
(я добавил -content в имя файла frontpage.html с ожиданием, что такой шаблон именования поможет сохранить имена файлов управляемыми.)
Ответ 4
Усы не поддерживают расширение шаблона.
Если вы действительно хотите расширение шаблона, вы можете использовать библиотечную цель, созданную с этой функциональностью, для вашего языка/рамки выбора.
FYI, я использую Node.js/Express, поэтому я, вероятно, в конечном итоге использую https://github.com/fat/stache
Ответ 5
В усах php поддерживается наследование шаблонов со версии 2.7.0.
https://github.com/bobthecow/mustache.php/wiki/BLOCKS-pragma
Вы можете узнать свою текущую версию из файла Mustache/Engine.php и найти строку, содержащую:
class Mustache_Engine
{
const VERSION = '2.8.0';
...
Ответ 6
Я играю с этим прямо сейчас в Python (заметьте, что я создатель Mako), добавив динамический контекст, который захватывает разделы, кажется, делает правильные вещи, хотя мне нужно будет проверить это много больше.
В основном мы используем lambdas, где "<" префикс указывает "наследовать от этого шаблона" (аналогично синтаксису, обсуждаемому в 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 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"}))
выход:
<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>
Я только что написал это через двадцать минут, и я только немного использовал handlebars.js в прошлом и pystache в первый раз, так что вся идея "усов" еще не для меня. Но это работает?
Ответ 7
Если вы довольны только кодом на стороне сервера, Nun - это шаблонная система с усами, расширяющая функциональность с помощью функции "переопределения шаблона" - моделируется на django. Хотя он работает, однако, его автор больше не поддерживает.
Ответ 8
В node.js вы можете использовать express-handlebars или hogan-express, чтобы иметь макеты шаблонов inna усов, но способ, которым они делают что-то другое, ни в одном из них вы не устанавливаете макет в самом шаблоне, макеты регистрируются в вашем коде приложения.