Подтвердить что ты не робот

Могут ли шаблоны 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}}), но они, кажется, просто включают.

Существует ли расширение шаблона для Усы? Или, в противном случае, существует, по крайней мере, некоторый шаблон проектирования, который эффективно включается, включает в себя эквиваленты расширения шаблонов.

4b9b3361

Ответ 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 в первый раз, так что вся идея "усов" еще не для меня. Но это работает?

Ответ 8

В node.js вы можете использовать express-handlebars или hogan-express, чтобы иметь макеты шаблонов inna усов, но способ, которым они делают что-то другое, ни в одном из них вы не устанавливаете макет в самом шаблоне, макеты регистрируются в вашем коде приложения.