web-dev-qa-db-fra.com

Les modèles de moustache peuvent-ils faire l'extension de modèle?

Je suis nouveau sur Moustache.

De nombreux langages de modèles (par exemple, Django/Jinja) vous permettront d'étendre un modèle "parent" comme ceci ...

base.html

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

frontpage.html

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

rendu frontpage.html

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

Je connais les partiels de Moustache (par exemple, {{>content}}), mais ceux-ci semblent être juste comprend .

Existe-t-il une extension de modèle pour Moustache? Ou, à défaut, existe-t-il au moins un modèle de conception qui transforme efficacement inclut en équivalents d'extension de modèle.

52
Chris W.

Je me suis récemment retrouvé dans le même bateau, sauf que je venais d'un milieu mako.

Moustache ne permet pas l'extension/l'héritage du modèle mais il y a quelques options disponibles à ma connaissance.

  1. Vous pouvez utiliser des partiels:

    {{>header}}
        Hello {{name}}
    {{>footer}}
    
  2. Vous pouvez injecter des fonctions de prétraitement de modèle dans le contexte de chaque modèle qui doit hériter d'une autre page:

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

    Hacher:

    {
       "name": "Walden",
       "extendBase": function() {
           return function(text) {
               return "<html><head></head>" + render(text) + "</body></html>"
           }
       }
    }
    
  3. Ajoutez et ajoutez le code HTML souhaité aux pages pertinentes de votre contrôleur.

  4. Ayez un modèle de mise en page ala:

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

    Et restituez le corps de votre contrôleur, en le transmettant au modèle de disposition sous la forme d'une variable nommée body.

  5. Implémentez l'héritage des modèles, pré-moustache, dans votre code qui charge les modèles.

Cependant, je n'utiliserais pas la triple moustache parce que je ne veux pas que du HTML non échappé apparaisse nulle part, c'est tout simplement trop risqué à mon avis.

Si quelqu'un d'autre a une meilleure solution à ce problème, j'aimerais aussi l'entendre, car je n'ai pas encore franchi le pas dans aucune de ces directions.

61
Walden

J'ai proposé cela aux spécifications de Moustache ici:

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

Actuellement, moustache.Java, hogan.js et phly_mustache prennent en charge l'héritage des modèles.

12
Sam Pullara

Dans la moustache php, l'héritage des modèles est pris en charge depuis la version 2.7.0.

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

Vous pouvez déterminer votre version actuelle à partir du fichier Moustache/Engine.php et rechercher la ligne contenant:

class Mustache_Engine
{
    const VERSION        = '2.8.0';
    ...
3
Basil Musa

Moustache ne fait pas d'extension de modèle.

Si vous voulez vraiment une extension de modèle, vous voudrez peut-être utiliser un objectif de bibliothèque construit avec cette fonctionnalité pour la langue/le cadre de votre choix.


Pour info, j'utilise Node.js/Express, donc je vais probablement finir par utiliser https://github.com/fat/stache

3
Chris W.

Vous pouvez utiliser des variables contenant du HTML. Une "triple moustache" comme {{{variable}}} renverra du code HTML non échappé. Ce n'est pas exactement la même chose que les extensions de modèle, mais vous pouvez afficher frontpage-content.html puis placer sa sortie dans une variable content qui est transmise à base.html.

(J'ai ajouté - content au frontpage.html nom de fichier avec l'espoir qu'un tel modèle de dénomination aidera à garder les noms de fichiers gérables.)

3
Kurt McKee

Je joue avec cela en ce moment dans Python (notez que je suis le créateur de Mako)), l'ajout dans un contexte dynamique qui capture des sections semble faire la bonne chose, même si je ' d besoin de tester cela beaucoup plus.

Fondamentalement, nous utilisons des lambdas, où un préfixe "<" indique "hériter de ce modèle" (similaire à la syntaxe discutée à https://github.com/mustache/spec/issues/38 ) et un préfixe "$" indique "c'est une section héritée".

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

Voici donc quelques modèles. base.mustache:

<html>

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

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

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


</html>

bonjour.mustache:

{{#<base}}

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

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

{{/<base}}

puis pour jouer avec trois niveaux de profondeur, subhello.mustache:

{{#<hello}}

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

{{/<hello}}

Rendre hello.mustache comme ceci:

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

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

production:

<html>

    new header

    new body, with some local key

    default footer, using some local key


</html>

Rendu subhello.mustache:

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

production:

<html>

    new header

    new body, with some local key

    im some new footer


</html>

Je viens d'écrire ceci en vingt minutes, et je n'ai utilisé un peu guidbars.js dans le passé et pystache pour la première fois en ce moment, donc l'idée de "moustache" n'est pas encore profonde pour moi. Mais cela semble fonctionner?

1
zzzeek

Si vous êtes satisfait d'un code côté serveur uniquement, Nun est un système de modèle semblable à Moustache avec des fonctionnalités étendues via sa fonction de remplacement de modèle - sur le modèle de Django. Bien que cela fonctionne, cependant, il n'est plus maintenu par son auteur.

0
mikemaccana

Dans node.js, vous pouvez utiliser express-guidons ou hogan-express pour avoir des mises en page dans les modèles de moustache, mais la façon dont ils font les choses est différente, dans aucun d'eux vous ne définissez la disposition au niveau du modèle lui-même, les dispositions sont enregistrées dans le code de votre application.

0
Alfgaar