- Maizzle Version: 0.7.3
- Node.js Version: 10.18.1
Description:
Hi. I want to thank you for first for having done for all of us maizzle framework. It's an awesome tool for writing email templates.
However, there is a thing i would like to report to you. I saw that this argument was already discussed in an other issue some months ago #69, and you've found already a solution, but this seems not to work properly.
The problem occurs when i try to extend three or more templates. Take this example:
i have the default layout, that is extended by a first template (first.njk)
---
layout: 'src/layouts/default.njk'
level: 1
---
{% block template %}
<table class="w-600 sm:w-full">
<tr>
<td class="p-48 sm:py-32 sm:px-24 text-center">
{% block level %}
{{ page.level }}
{% endblock %}
{% block content %}
first level content
{% endblock %}
</td>
</tr>
</table>
{% endblock %}
Then i have a second template, called "second.njk", that extends the first
---
layout: 'src/templates/first.njk'
level: 2
---
{% block content %}
second level content that overwrites the first one {{ page.level }}
{% endblock %}
Here everything is still working, but when you try to add a third template (third.njk), that extends the second, there are some obvious problems
---
layout: 'src/templates/second.njk'
level: 3
---
{% block content %}
third level content that overwrites the second one {{ page.level }}
{% block other_block %}
new
{% endblock %}
{% endblock %}
The first problem is that i want to extend the template and define everytime just the "content" block. I don't want to define everytime the "template" block, because, in this case, i have there just some layout (markup and css) and i don't want to rewrite it everytime. Rewriting the "content" block in "second.njk" works, and also the layout (markup and css) from "first.njk" is there. But when i overwrite the "content" block in "third.njk", the layout is no more there.
The second problem is that i can't use {{ super() }}
in the blocks: let's say i want to take everything from "content" block of "first.njk" also in "second.njk", define something else there and then take all this content in "third.njk" with another {{ super }}
, defining even here something else but keeping everything was already done in other templates. This doesn't work.
The reason of why this is not working is in "toString.js":
html = layout ? `${blockStart} extends "${layout}" ${blockEnd}\n${html}` : html
html = nunjucks.renderString(html, { page: config, env: options.env, css: compiledCSS })
while (fm(html).attributes.layout) {
const front = fm(html)
html = `${blockStart} extends "${front.attributes.layout}" ${blockEnd}\n${blockStart} block template ${blockEnd}${front.body}${blockStart} endblock ${blockEnd}`
html = nunjucks.renderString(html, { page: config, env: options.env, css: compiledCSS })
}
Maizzle here is doing something that nunjucks already comes with, in another way, that causes the problems that i mentioned above.
The solution would be to remove the while loop, and to use the {% extends "template" %}
syntax, right after the definition of the front matter. This works, inheritance works very well, and i can call {{ super() }}
in every inheritance level, in the same block. I could also define just the blocks that i want, in every level, without having to define the "template" block everytime. Just this would be enough to solve
html = layout ? `${blockStart} extends "${layout}" ${blockEnd}\n${html}` : html
html = nunjucks.renderString(html, { page: config, env: options.env, css: compiledCSS })
In this case, who is using just one level of inheritance (template that extends the layout), could omit the {% extends "template" %}
syntax, and who's doing multiple levels of inheritance should use it for all the levels.
In my opinion nunjucks is a very, very powerful tool, and maizzle should use all the best features that nunjucks offers. The multilevel inheritance gives me the possibility to set the "skeleton" of my email template just once, and change then the content of the emails that i have to send.