tbranyen / combyne

A template engine that works the way you expect.
MIT License
144 stars 19 forks source link

More flexible template inheritance #76

Open kadamwhite opened 9 years ago

kadamwhite commented 9 years ago

Currently one kind of inheritance exits:

var template = "{%extend layout as content%}<h1>Header</h1>{%endextend%}";
var page = combyne(template);

// Register the layout template into the page template.
page.registerPartial("layout", combyne("<body>{%partial content%}</body>"));

page.render(context); // "<body><h1>Header</h1></body>"

(Note: if two {%extend ... %} statements exist in a file, Combyne throws an error.)

Other templating systems, notably Nunjucks and Handlebars, support the concept of blocks, which can be seen as multiple-inheritance. A Nunjucks example would have a layout file like this:

{% block header %}This is the default content{% endblock %}
<section class="left">{% block left %}{% endblock %}</section>
<section class="right">{% block right %}This is more content{% endblock %}</section>

so that rendering a template of this sort

{% extends "parent.html" %}
{% block left %}This is the left side!{% endblock %}
{% block right %}This is the right side!{% endblock %}

would generate

This is the default content
<section class="left">This is the left side!</section>
<section class="right">This is the right side!</section>

where each block statement would extend the relevant partial within the extended layout. (Nunjucks docs on block inheritance)

This issue exists to discuss whether this feature should be added, and how it should be implemented. Support for blocks is provisionally on the list for a 1.0 milestone: #73


Hypothetical syntax for block support

One option would be to just support multiple extends in one file: Render this template

{%extend layout1 as partial1%}<h1>Header</h1>{%endextend%}
{%extend layout1 as partial2%}<h2>Subheader</h2>{%endextend%}

with layout "layout1"

<div class="one">{%partial partial1%}</div>
<div class="two">{%partial partial2%}</div>

yields

<div class="one"><h1>Header</h1></div>
<div class="two"><h2>Subheader</h2></div>

Extending from multiple layouts

If different templates were extended, one intuitive option would be to have their output concatenated:

{%extend layout1 as partial1%}<h1>Header</h1>{%endextend%}
{%extend layout2 as partial1%}<h2>Subheader</h2>{%endextend%}

layout1:

<div class="one">{%partial partial1%}</div>

layout2:

<div class="two">{%partial partial1%}</div>

yields

<div class="one"><h1>Header</h1></div>
<div class="two"><h2>Subheader</h2></div>