Can Mustache Templates do template extension?

后端 未结 9 510
醉话见心
醉话见心 2021-01-30 06:39

I\'m new to Mustache.

Many templating languages (e.g., Django / Jinja) will let you extend a \"parent\" template like so...

ba

相关标签:
9条回答
  • 2021-01-30 07:11

    If you're happy with a server-side only code, Nun is a Mustache-like templating system with extends functionality via its 'template overrides' feature - modelled on django. While it works, however, it is no longer maintained by its author.

    0 讨论(0)
  • 2021-01-30 07:14

    Mustache doesn't do template extension.

    If you really want template extension then you may want to use a library purpose built with this functionality for you language/framework of choice.


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

    0 讨论(0)
  • 2021-01-30 07:20

    I'm playing around with this right now in Python (note I'm the creator of Mako), adding in a dynamic context that captures sections seems to be doing the right thing, though I'd need to test this a lot more.

    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
    

    So here's some templates. 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}}
    

    and then to play with three levels deep, subhello.mustache:

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

    Rendering hello.mustache like this:

    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>
    

    Rendering 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>
    

    I just wrote this in twenty minutes, and I've only used handlebars.js a little bit in the past and pystache for the first time just now so the whole "mustache" idea is not deep for me yet. But this seems to work ?

    0 讨论(0)
提交回复
热议问题