Can Mustache templates do template extension?

I am new to Mustache.

Many template languages ​​(for example, Django / Jinja ) will allow you to extend the "parent" template, for example ...

base.html

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

frontpage.html

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

rendered frontpage.html

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

I know the partial parts of the Mustache (like {{>content}} ), but they seem to just include.

Is there a template extension for Mustache? Or, otherwise, there is at least some design pattern that is effectively included that includes the equivalents of extension patterns.

+47
javascript python ruby templates mustache
Oct 28 '11 at 6:37 a.m.
source share
8 answers

I recently ended up in the same boat, except that I came from the background of mako.

Mustache does not allow extension / inheritance of the template, but there are several options available to you. I do not know how to do that.

  • You can use partials:

     {{>header}} Hello {{name}} {{>footer}} 
  • You could insert template preprocessing functions into the context for each template that should 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>" } } } 
  • Prepare and add the desired HTML to the appropriate pages of your controller.

  • You have a layout template:

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

    And visualize the body in the controller, passing it to the layout template as a variable called body .

  • Embed template inheritance, pre-whiskers, in your code that loads the templates.

However, I would not use a triple mustache, because I do not want unescaped HTML to appear anywhere, this is too risky, in my opinion.

If someone has a better solution to this problem, I would also like to hear this, since I have not done a single dive in any of these areas.

+56
Nov 03 2018-11-11T00:
source share

I suggested this for the specification for Mustache:

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

Mustache.java, hogan.js, and phly_mustache currently support template inheritance.

+12
Jul 24 2018-12-12T00:
source share

You can use variables containing HTML. Triple mustache, such as {{{variable}}} , returns unshielded HTML. This is not exactly the same as the template extension, but you can display frontpage-content.html and then put its output in the content variable, which will be passed to base.html .

(I added -content to the frontpage.html file name with the expectation that such a naming pattern would help keep the file names manageable.)

+3
Nov 02 '11 at 4:20
source share

Mustache does not support template extension.

If you really want a template extension, you can use the library target created with this functionality for your language / selection frame.




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

+3
Nov 04 '11 at 5:12
source share

The php mustache supports template inheritance from version 2.7.0.

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

You can find out your current version from the Mustache / Engine.php file and find a line containing:

 class Mustache_Engine { const VERSION = '2.8.0'; ... 
+2
May 28 '15 at 11:47
source share

I'm playing with it right now in Python (note that I'm the creator of Mako), adding a dynamic context that grabs sections seems to be doing the right thing, although I will need to check this out a lot more.

We mainly use lambdas, where the "<" prefix indicates "inherit from this template" (similar to the syntax discussed at https://github.com/mustache/spec/issues/38 ), and the prefix "$" indicates "this is 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 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 are 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 play with three levels of depth, subhello.mustache:

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

Rendering hello.mustache as follows:

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

exit:

 <html> new header new body, with some local key default footer, using some local key </html> 

subhello.mustache rendering:

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

exit:

 <html> new header new body, with some local key im some new footer </html> 

I just wrote this in twenty minutes, and I only used handlebars.js a little in the past and pystache for the first time, so the whole idea of ​​a "mustache" is not for me. But does it work?

+1
Dec 30 '12 at 23:05
source share

If you are only happy with the server-side code, Nun - a template system with a mustache that extends functionality with the help of the "template override" function - is modeled on django. Although it works, however, its author no longer supports it.

0
Mar 13 2018-12-12T00:
source share

In node.js, you can use express-handlebars or hogan-express to have mustache inna template layouts, but the way they do something else, in none of them you set the layout in the template itself, the layouts are registered in your application code.

0
Jul 27 '15 at 0:21
source share



All Articles