Bıyık Şablonları şablon uzantısı yapabilir miyim?

Bıyık için yeniyim.

Birçok templasyon dili (ör. Django / Jinja ), "ebeveyn" şablonunu bu şekilde genişletmenize izin verir.

base.html

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

frontpage.html

{% extends "base.html" %}
{% block content %}

Foobar!

{% endblock %}

rendered frontpage.html

<html><head></head>
    <body>
    

Foobar!

    </body>
</html>

I'm aware of Mustache's partials (e.g., {{>content}}), but those seem to be just includes.

Mustache için şablon uzantısı var mı? Ya da başarısız olursa, en azından içerir öğesini şablon uzantısı eşdeğerlerine çeviren en azından bazı tasarım desenleri var.

51

8 cevap

Geçenlerde kendimi aynı teknede buldum, ama mako arka planından geldim.

Bıyık, şablon uzantısı/mirasına izin vermez, ancak bildiğim birkaç seçenek vardır.

  1. You could use partials:

    {{>header}}
        Hello {{name}}
    {{>footer}}
    
  2. You could inject template pre-processing functions into the context for each template that needs to inherit from some other page:

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

    Hash:

    {
       "name": "Walden",
       "extendBase": function() {
           return function(text) {
               return "<html><head></head>" + render(text) + "</body></html>"
           }
       }
    }
    
  3. Prepend and append the desired HTML to the relevant pages in your controller.

  4. Have a layout template ala:

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

    And render the body in your controller, passing that to the layout template as a variable named body.

  5. Implement template inheritance, pre-mustache, in your code that loads templates.

I wouldn't, however, use the triple mustache because I don't want unescaped HTML to be appearing anywhere, it's just too risky in my opinion.

If someone else has a better solution to this problem I'd love to hear it as well, since I haven't yet taken the plunge in any one of these directions.

59
katma
Öyleyse, PHP'de kullanmanın bir yolu benzer bir kısmi mi?
katma yazar Alvaro, kaynak
# 4 "üçlü bıyık" olmalı - {{{body}}}
katma yazar Chris W., kaynak
Evet, maalesef benim için # 4 olan kuralları çözüyorsun. Cevabı güncelledim.
katma yazar Walden, kaynak
Sonuç olarak, yeniden kullanılabilir alt şablonlar oluşturmak ve şablon yükleme kodunda (yani # 5) kalıtım uygulamak genel olarak çok daha esnek ve daha güvenlidir. Şablon kalıtımı ile ilgili problem, dış şablon yazılırken, bir alt şablonda neyin gerekli (veya gerekli değil) konusunda iyi bir fikir sahibi olamayacağıdır. Bu genellikle dış şablonda belirli bir alt sayfa için (ancak başka bir şey için gereksiz) gerekli olabilecek JS/CSS'nin dahil edilmesine yol açar. Şablon mirasını kullanırken bu sorunun etrafındaki tek yol, JS/CSS gereksinimlerini bir değişken olarak iletmektir.
katma yazar Walden, kaynak
katma yazar Walden, kaynak
(@Walden Belki de listenizde 0 veya no. 6 eklemeniz ve Hoogian'dan bahsetmelisiniz. Yine de yorum eklemek için teşekkürler :-))
katma yazar KajMagnus, kaynak

Bunu burada Bıyık için şartnameye önerdim:

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

Şu anda mustache.java, hogan.js ve phly_mustache destek şablonu kalıtım.

12
katma
Hogan.js ile ilgili olarak, dokümantasyondan haberiniz olmasa da: github.com /twitter/hogan.js/issues/70
katma yazar Paul D. Waite, kaynak
GRMustache da öyle.
katma yazar Gwendal Roué, kaynak

Bıyık şablon uzantısı yapmaz.

Eğer gerçekten şablon uzantısı istiyorsanız, dil/çerçeve seçiminiz için bu işlevsellik ile oluşturulmuş bir kütüphane amacı kullanmak isteyebilirsiniz.


FYI, I'm using Node.js/Express, so I will probably end up using https://github.com/fat/stache

3
katma
W Stash korunmaz ve hogan.js önerisi, uzantıları uygulamak için görünmüyor.
katma yazar mikemaccana, kaynak
Twitter'ın Hoogyanı şimdi mirasa destek veriyor gibi görünüyor. Bu son işleme bakın: Hogan 3. Şablon devralma ekle ...
katma yazar KajMagnus, kaynak

Bıyık PHP, şablon kalıtım 2.7.0 sürümünden beri desteklenmektedir.

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

Güncel sürümünüzü Bıyık/Motor.php dosyasından bulabilir ve aşağıdakileri içeren satırı arayabilirsiniz:

class Mustache_Engine
{
    const VERSION        = '2.8.0';
    ...
3
katma

HTML içeren değişkenleri kullanabilirsiniz. {{{}}}} gibi bir "üçlü bıyık", çıkarılmamış HTML'yi döndürecektir. Şablon uzantıları ile tam olarak aynı değildir, ancak frontpage-content.html 'yi oluşturabilir ve ardından çıktısını tabanına geçirilen content değişkenine koyabilirsiniz. html .

( frontpage.html dosya adına -gizli ekledim. Böyle bir isimlendirme modelinin dosya isimlerini yönetilebilir tutmaya yardımcı olması bekleniyor.)

3
katma

Şu anda Python'da (Mako'nun yaratıcısı olduğumu not et) şu anda oynuyorum, bölümleri yakalayan dinamik bir bağlam ekleyerek, bunu doğru bir şekilde test etmem gerekiyor olsa da, bunu daha çok test etmem gerekiyor.

Basically we are using lambdas, where a "<" prefix indicates "inherit from this template" (similar to the syntax discussed at https://github.com/mustache/spec/issues/38) and a "$" prefix indicates "this is an inherited section".

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

İşte bazı şablonlar. base.mustache:

<html>

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

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

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


</html>

hello.mustache:

{{#

ve daha sonra üç seviyeli derinlerle oynamak için, subhello.mustache:

{{#

Bu gibi hello.mustache render:

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

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

çıktı:

<html>

    new header

    new body, with some local key

    default footer, using some local key


</html>

Renderleme subhello.mustache:

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

çıktı:

<html>

    new header

    new body, with some local key

    im some new footer


</html>

Bunu sadece yirmi dakika içinde yazmıştım, ve sadece geçmişte biraz tutacağım ve sadece ilk kez tıpkı "mustache" fikrinin henüz benim için derin olmadığını anladım. Ama bu işe yarıyor mu?

1
katma

Node.js'de ifade tutamaçlarını veya hogan-express düzenleri inna bıyık şablonlarına sahip olmak için, ancak yaptıklarının şekli farklıdır, hiçbiri düzeninizi şablonun kendisinde ayarlarsınız. , düzenler uygulama kodunuza kaydedilir.

0
katma