I\'m new to Mustache.
Many templating languages (e.g., Django / Jinja) will let you extend a \"parent\" template like so...
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.
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
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 ?