Czy szablony wąsów mogą rozszerzać szablon?

Jestem nowy w wąsach.

Wiele języków szablonów (np. Django / Jinja ) pozwoli ci rozszerzyć szablon "rodzica" w ten sposób...

Baza.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>

Jestem świadomy częściowych (np. {{>content}}), ale te wydają się być tylko zawiera.

Czy istnieje rozszerzenie szablonu dla wąsów? Lub, w przeciwnym razie, jest tam co najmniej niektóre wzorce projektowe, które skutecznie zamieniają , zawierają W odpowiedniki rozszerzenia szablonu.

Author: Paul D. Waite, 2011-10-28

9 answers

Ostatnio znalazłem się w tej samej łodzi, z wyjątkiem tego, że pochodzę z Mako.

Wąsy nie pozwalają na rozszerzenie/dziedziczenie szablonów, ale jest kilka dostępnych opcji, o których wiem.

  1. Przydałyby się częściowe:

    {{>header}}
        Hello {{name}}
    {{>footer}}
    
  2. Możesz wprowadzić funkcje wstępnego przetwarzania szablonu do kontekstu dla każdego szablonu, który musi dziedziczyć z innej strony:

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

    Hash:

    {
       "name": "Walden",
       "extendBase": function() {
           return function(text) {
               return "<html><head></head>" + render(text) + "</body></html>"
           }
       }
    }
    
  3. Prepend i Dołącz żądany kod HTML do odpowiednich stron w kontrolerze.

  4. Mieć szablon layoutu:

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

    I renderuje ciało w kontrolerze, przekazując je do szablonu układu jako zmienną o nazwie body.

  5. Zaimplementuj dziedziczenie szablonów, pre-wąsy, w kodzie, który ładuje szablony.

Nie używałbym jednak potrójnych wąsów, ponieważ nie chcę, aby nigdzie nie pojawiał się niezaklejony HTML, to po prostu zbyt ryzykowne moim zdaniem.

Jeśli ktoś inny ma lepsze rozwiązanie tego problemu, chciałbym go również usłyszeć, ponieważ jeszcze nie podjąłem się zanurzenia w żadnej z tych stron.

 62
Author: Walden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-04 16:07:24

Zaproponowałem to do specyfikacji wąsów tutaj:

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

Obecnie wąsy.java, hogan.js i phly_mustache wspierają dziedziczenie szablonów.

 12
Author: Sam Pullara,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-24 19:07:19

Możesz użyć zmiennych zawierających HTML. "Potrójne wąsy" jak {{{variable}}} zwrócą nieskazitelny HTML. Nie jest to dokładnie to samo co rozszerzenia szablonów, ale możesz renderować frontpage-content.html, a następnie umieścić jego wyjście w zmiennej content, która zostanie przekazana do bazy .html .

(dodałem -content do frontpage.html nazwa pliku z oczekiwaniem, że taki wzorzec nazewnictwa pomoże w zarządzaniu nazwami plików.)

 3
Author: Kurt McKee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-02 04:20:57

Wąsy nie rozszerzają szablonu.

Jeśli naprawdę chcesz rozszerzyć szablon, możesz użyć biblioteki zbudowanej z tej funkcjonalności dla wybranego języka/frameworka.


Dla twojej wiadomości, używam Node.js / Express, więc pewnie skończę używając https://github.com/fat/stache

 3
Author: Chris W.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-04 05:12:33

W PHP mustache dziedziczenie szablonów jest obsługiwane od wersji 2.7.0.

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

Możesz dowiedzieć się o swojej bieżącej wersji z pliku Mustache / Engine.php i wyszukaj linię zawierającą:

class Mustache_Engine
{
    const VERSION        = '2.8.0';
    ...
 3
Author: Basil Musa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-28 11:47:01

Bawię się tym teraz w Pythonie (zauważ, że jestem twórcą Mako), dodawanie w dynamicznym kontekście, który przechwytuje sekcje, wydaje się robić dobrą rzecz, choć musiałbym to przetestować znacznie więcej.

Zasadniczo używamy lambda, gdzie przedrostek " https://github.com/mustache/spec/issues/38 ), a przedrostek " $ "oznacza" to jest dziedziczona sekcja".

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

Więc oto kilka szablonów. baza.wąsy:

<html>

{{#$header}}
    default header
{{/$header}}

{{#$body}}
    default body
{{/$body}}

{{#$footer}}
    default footer, using {{local key}}
{{/$footer}}


</html>
Witam.wąsy:
{{#<base}}

{{#$header}}
    new header
{{/$header}}

{{#$body}}
    new body, with {{local key}}
{{/$body}}

{{/<base}}

A potem grać z trzech poziomów głęboko, subhello.wąsy:

{{#<hello}}

{{#$footer}}
    im some new footer
{{/$footer}}

{{/<hello}}

Rendering hello.wąsy takie:

renderer = pystache.Renderer(search_dirs=["./templates/"])

print renderer.render_name("hello",
                    NameSpace(renderer, {"local key": "some local key"}))

Wyjście:

<html>

    new header

    new body, with some local key

    default footer, using some local key


</html>

Rendering subhello.wąsy:

print renderer.render_name("subhello",
                    NameSpace(renderer, {"local key": "some local key"}))

Wyjście:

<html>

    new header

    new body, with some local key

    im some new footer


</html>

Napisałem to w 20 minut, a używałem tylko kierownicy.js trochę w przeszłości i pystache po raz pierwszy właśnie teraz więc cały pomysł "wąsów" nie jest głęboki dla ja jeszcze. Ale to chyba działa ?

 1
Author: zzzeek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-30 23:05:08

Jeśli jesteś zadowolony z kodu tylko po stronie serwera, Nun jest wąsatym systemem szablonów z rozszerzoną funkcjonalnością poprzez funkcję 'przesłania szablonów' - wzorowaną na django. Choć działa, jednak nie jest już utrzymywana przez jego autora.

 0
Author: mikemaccana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-13 21:56:44

In node.js możesz użyć express-handlebars lub hogan-express aby mieć layouty inne szablony wąsów, ale sposób ich działania jest inny, w żadnym z nich nie ustawiasz układu na samym szablonie, layouty są rejestrowane w kodzie aplikacji.

 0
Author: Alfgaar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-27 00:21:41

Napisałem krótki kod, aby umożliwić rozszerzanie i tworzenie układów. .

Jeśli nie chcesz kopiować / wklejać nagłówka / stopki lub paska menu, który jest powtarzany we wszystkich poddziałach administratora, za każdym razem, gdy renderujesz stronę / widok, wystarczy użyć funkcji: build następującej klasy, którą możesz użyć jako modułu utils

class MustacheLayout {
  constructor() {
    if (!MustacheLayout.instance) {
      MustacheLayout.instance = this;
    }
    return MustacheLayout.instance;
  }

  async build(...layers) {
    let previousLayer = '';
    let combinedLayout = '';
    for (const layer of layers) {
      const { name: layerName } = layer;
      let { data: layerData } = layer;
      if (!layerData) layerData = {};
      layerData.child = previousLayer;
      combinedLayout = await this.renderHtml(layerName, layerData);
      previousLayer = combinedLayout;
    }
    return combinedLayout;
  }

  renderHtml(viewName, data) {
    return new Promise((resolve, reject) => {
      this.app.render(viewName, data, (error, html) => {
        if (error) reject(error);
        resolve(html);
      });
    });
  }

  setExpressApp(expressApp) {
    this.app = expressApp;
  }
}

module.exports = new MustacheLayout();
  • na twoim serwerze.plik JS / index aplikacji express, dodaj instancję aplikacji do naszej klasy.
//import the class const mustacheLayout = require('') //
const app = express();;
mustacheLayout.setExpressApp(app);

Controller

Umieść całą warstwę w funkcji build jako parametry,

Warning : - musisz szanować porządek, od najmniejszego układu do największego (baza.html) - właściwości danych powinny być nazwane tak jak w widoku

const layout = require('mustache-layout');

router.get('/edit', async (_, res) => {
    const user = 'admin'
    const html = await layout.build(
        { name: 'admin/edition/editor.view.html', data: { user } },
        { name:'layout/base.view.html' }
    )
    return res.send(html);
});

Widok

Warning musisz użyć słowa kluczowego child na stronach widoku układu. don ' t forget triple braces {{{ }}}

Użyj przekazanych danych tutaj

<!-- ditor.view.html -->
<div> {{ user }} </div>
<!-- base.view.html -->
<!DOCTYPE html>
<html lang="en">
<body>
    {{ > layout/header.view }}
    <div class="main">
        <div class="layout-content">
            {{{ child }}}
        </div>
    </div>
    {{ > layout/footer.view }}
</body>
</html>

Jeśli potrzebujesz wersji pakietu tego kodu sprawdź mustache-layout-s

 0
Author: blade-sensei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-22 15:26:37