Can Mustache Templates do template extension?

后端 未结 9 621
醉话见心
醉话见心 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: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:

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

    hello.mustache:

    {{#

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

    {{#

    Rendering hello.mustache like this:

    renderer = pystache.Renderer(search_dirs=["./templates/"])
    
    print renderer.render_name("hello",
                        NameSpace(renderer, {"local key": "some local key"}))
    

    output:

    
    
        new header
    
        new body, with some local key
    
        default footer, using some local key
    
    
    
    

    Rendering subhello.mustache:

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

    output:

    
    
        new header
    
        new body, with some local key
    
        im some new footer
    
    
    
    

    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 ?

提交回复
热议问题