Могут ли усы шаблоны сделать расширение шаблона? - PullRequest
52 голосов
/ 28 октября 2011

Я новичок в Усы.

Многие языки шаблонов (например, Django / Jinja ) позволят вам расширить «родительский» шаблон, как это происходит...

base.html

<html><head></head>
    <body>
    {% block content %}{% endblock %}
    </body>
</html>

frontpage.html

{% extends "base.html" %}
{% block content %}<h1>Foobar!</h1>{% endblock %}

предоставлено frontpage.html

<html><head></head>
    <body>
    <h1>Foobar!</h1>
    </body>
</html>

Мне известно оУсы усы (например, {{>content}}), но они, кажется, просто включают .

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

Ответы [ 8 ]

61 голосов
/ 04 ноября 2011

Я недавно оказался в той же лодке, за исключением того, что я из Мако.

Усы не допускают расширения / наследования шаблонов, но есть несколько доступных вам вариантов, о которых я знаю.

  1. Вы можете использовать частичные значения:

    {{>header}}
        Hello {{name}}
    {{>footer}}
    
  2. Вы можете добавить функции предварительной обработки шаблона в контекст для каждого шаблона, который должен наследоваться от какой-либо другой страницы:

    {{#extendBase}}      
        Hello {{name}}
    {{/extendBase}} 
    

    Hash:

    {
       "name": "Walden",
       "extendBase": function() {
           return function(text) {
               return "<html><head></head>" + render(text) + "</body></html>"
           }
       }
    }
    
  3. Добавить и добавить нужный HTML-код на соответствующие страницы вашего контроллера.

  4. Есть шаблон макета аля:

    {{>header}}
        {{{body}}}
    {{>footer}}
    

    И визуализировать тело в вашем контроллере, передав его в шаблон макета в виде переменной с именем body.

  5. Внедрите в свой код предварительное усвоение шаблонов, которое загружает шаблоны.

Однако я бы не стал использовать тройные усы, потому что не хочу, чтобы неэкранированный HTML-код появлялся где-либо, на мой взгляд, он слишком рискованный.

Если у кого-то еще есть лучшее решение этой проблемы, я бы тоже хотел это услышать, поскольку я еще не сделал ни одного из этих шагов.

12 голосов
/ 24 июля 2012

Я предложил это в спецификации для Усов здесь:

https://github.com/mustache/spec/issues/38

В настоящее время mustache.java, hogan.js и phly_mustache поддерживают наследование шаблонов.

3 голосов
/ 28 мая 2015

В усиках php наследование шаблонов поддерживается начиная с версии 2.7.0.

https://github.com/bobthecow/mustache.php/wiki/BLOCKS-pragma

Вы можете узнать текущую версию из файла Mustache / Engine.php и найти строку, содержащую:

class Mustache_Engine
{
    const VERSION        = '2.8.0';
    ...
3 голосов
/ 04 ноября 2011

Усы не делают расширение шаблона.

Если вы действительно хотите расширение шаблона, вы можете использовать библиотечное назначение, построенное с этой функциональностью, для вашего языка / фреймворка.


К вашему сведению, я использую Node.JS / Express, так что я, вероятно, в конечном итоге буду использовать https://github.com/fat/stache

3 голосов
/ 02 ноября 2011

Вы можете использовать переменные, содержащие HTML.«Тройные усы», подобные {{{variable}}}, возвращают неэкранированный HTML.Это не совсем то же самое, что и расширение шаблона, но вы можете отобразить frontpage-content.html и затем поместить его вывод в переменную content, которая передается в base.html .

(я добавил -content к имени файла frontpage.html , ожидая, что такой шаблон именования поможет сохранить управляемость имен файлов.)

1 голос
/ 31 декабря 2012

Я сейчас играю с этим в 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теперь, так что вся идея "усов" еще не глубока для меня. Но, похоже, это работает?

0 голосов
/ 27 июля 2015

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

0 голосов
/ 14 марта 2012

Если вас устраивает код только на стороне сервера, Nun - это шаблонная система, похожая на Усы, с расширенными функциональными возможностями за счет функции «переопределения шаблонов» - по образцу django.Хотя это работает, однако, его больше не поддерживает его автор.

...