Skip to main content
Topic: 2.0: mustache template engine?  (Read 9311 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

2.0: mustache template engine?

I'd personally favour to move to a template engine for 2.0.. this is a quick working draft made in mustache.php (very simple to learn, almost logicless).

the current code taken from ManageMail.template.php
Code: (ManageMail.template.php) [Select]
function template_mail_queue()
{
global $context, $txt;

echo '
<div id="manage_mail">
<div id="mailqueue_stats">
<h2 class="category_header">', $txt['mailqueue_stats'], '</h2>
<div class="content">
<dl class="settings">
<dt><strong>', $txt['mailqueue_size'], '</strong></dt>
<dd>', $context['mail_queue_size'], '</dd>
<dt><strong>', $txt['mailqueue_oldest'], '</strong></dt>
<dd>', $context['oldest_mail'], '</dd>
</dl>
</div>
</div>';

template_show_list('mail_queue');

echo '
</div>';
}

the same as mustache template.
Code: (ManageMail.html) [Select]
<div id="manage_mail">
<div id="mailqueue_stats">
<h2 class="category_header">{{txt.mailqueue_stats}}</h2>
<div class="content">
<dl class="settings">
<dt><strong>{{txt.mailqueue_size}}</strong></dt>
<dd>{{context.mail_queue_size}}</dd>
<dt><strong>{{txt.mailqueue_oldest}}</strong></dt>
<dd>{{context.oldest_mail}}</dd>
</dl>
</div>
</div>
{{>mail_queue_list}}
</div>

IMO there are some big benefits for designers (and developers):
- easy readable code (almost simple html files)
- reduced syntax errors while developing code (PHP is sometimes complex, especially if the templates are using nested ternary operators)
- syntax highlightning in editors (makes it easier to find a syntax error)
- reusable code (mustache templates can be rendered via PHP or Javascript)

Not sure if you like it? I'd be interested in your opinions regarding a template engine..

Thorsten "TE" Eurich
------------------------

Re: 2.0: mustache template engine?

Reply #1

Back in the early 2000s I experimented with a then-popular template engine (Smarty) in place of just sticking with a self-imposed subset of PHP. It worked fine, but after playing around with it for a while I could only conclude that it was just a redundant extra layer of complexity.

Code: [Select]
{if !$error}
<h2>User info for {$member}</h2>
<dl>
<dt>Member name:</dt><dd>{$member}</dd>
{if $showemail eq 1}
<dt>Email Address:</dt><dd>{$email}</dd>
{if $altemail}<dt>Alternate Email:</dt><dd>{$altemail}</dd>{/if}
{/if}
{if $ICQ}<dt>ICQ Handle:</dt><dd>{$ICQ}</dd>{/if}
{if $AIM}<dt>AIM Handle:</dt><dd>{$AIM}</dd>{/if}
{if $MSN}<dt>MSN Handle:</dt><dd>{$MSN}</dd>{/if}
{if $fname}<dt>Real name:</dt><dd>{$fname} {$mname} {$lname}</dd>{/if}
{if $bday > 0}
<dt>Birthday:</dt><dd>{$bday} - {$bmonth} - {$byear}</dd>
{/if}
{if $location}<dt>Location:</dt><dd>{$location}</dd>{/if}
{if $occupation}<dt>Occupation:</dt><dd>{$occupation}</dd>{/if}
{if $hobbies}<dt>Hobbies:</dt><dd>{$hobbies}</dd>{/if}
{if $skills}<dt>Skills:</dt><dd>{$skills}</dd>{/if}
{if $title}<dt>Title:</dt><dd>{$title}</dd>{/if}
{if $about}<dt>About user:</dt><dd>{$about}</dd>{/if}
{if $signature}<dt>Forum signature:</dt><dd>{$signature}</dd>{/if}
</dl>
<h2>{$member}'s Gallery</h2>
{foreach from=$images item=row2}
Title: {$row2.title}<br/>Subtitle: {$row2.subtitle}<br/>Size: {$row2.width}x{$row2.height}
<br/>
<a href="gallery.php?iid={$row2.imageid}"><img src="image.php?img={$row2.imageid}" width="200" height="160" border="0"/></a>
<br/>
{/foreach}
{/if}

Quote- easy readable code (almost simple html files)
Disagree. It's just another syntax. Slightly more elegant than PHP in some cases,  but I think this is much closer to the bottom example while retaining regular PHP.

Quote- reduced syntax errors while developing code (PHP is sometimes complex, especially if the templates are using nested ternary operators)
Agree and disagree. Sounds more like a style guide issue, a style enforcement issue, or a legacy code (style) issue.

Quote- reusable code (mustache templates can be rendered via PHP or Javascript)
It looks like this Mustache thing is "only" 10 kB?[1] I suppose that could be acceptable.

tl;dr Seems redundant but probably harmless.
In contrast with that >50 kB Angular behemoth.

Re: 2.0: mustache template engine?

Reply #2

I think a template engine would be interesting.
I thought about it for a while myself, but never managed to even start reading twig documentation. lol

I'm not against for sure, the advantages I see are mainly two:
1) we stop having at least one potential security risk (I know is just a part of the big picture, because the package manager is not different but at least is one less) not having to write directly to php files on the server,
2) we would give end-users a much more user-friendly way of dealing with template edits (i.e. no need to explain that to add a google analytics script they have to either learn a bit of php or install an addon that may or may not work because "someone" forgot to update it xD).

Then, as side-effect, there would be the fact that becoming the templates html files, we would be forced to avoid certain things we have in the templates right now (yes, @Frenzie they are either legacy stuff or some fancy coding we did, but still with php templates it is possible to do it, while with a template engine it is not (always, or at least so heavily) possible).

On the "which one to use", I always looked at twig because, as far as I understood, it would allow us a much smoother transition since Twig can use php files as templates and has pretty much the same features as php (conditionals loops, etc.).
As far as I can see, Mustache would instead mean a one-time-full-rewrite of the whole template, that may also require some considerable work on the backend to provide exactly what we need to display (since we nowadays do quite a bit of fancy stuff in the templates).
That said, I expect it would be possible to use some dirty workaround at least during the development phase (like for example use the current php templates to instantiate Mustache and work on one template at a time) to make the transition easier to manage.
Bugs creator.
Features destroyer.
Template killer.

Re: 2.0: mustache template engine?

Reply #3

Quote- reduced syntax errors while developing code (PHP is sometimes complex, especially if the templates are using nested ternary operators)
All the processing is supposed to be done on the backend. I am a firm believer in lean templates where processing (checks for isset and so on, ternary operators) is to be kept to a bare minimum, avoiding them if at all possible.
LiveGallery - Simple gallery addon for ElkArte

Re: 2.0: mustache template engine?

Reply #4

@emanuele Instant Twig dislike from me, sorry. While the Twig blurb superficially seems to have been written to appeal to me, I find its first argument a spurious, distasteful strawman.

QuoteConcise: The PHP language is verbose and becomes ridiculously verbose when it comes to output escaping:

Code: [Select]
<?php echo $var ?>
<?php echo htmlspecialchars($var, ENT_QUOTES, 'UTF-8') ?>

In comparison, Twig has a very concise syntax, which make templates more readable:

Code: [Select]
{{ var }}
{{ var|escape }}
{{ var|e }}         {# shortcut to escape a variable #}

That may be truth-adjecent, but obviously, as @live627 said, that should be done before it reaches the template.

Or you could define a function like escape, esc or e (also, hasn't anyone heard of ViewModels?) if you want to do it in the template itself. Obviously {{ var|e }} is slightly more concise than <?php echo e($var) ?> but basic critical thinking and courtesy demand that you steelman the competition rather than serving up a strawman.

QuoteTemplate oriented syntax: Twig has shortcuts for common patterns, like having a default text displayed when you iterate over an empty array:
And PHP doesn't? O-o

QuoteFull Featured: Twig supports everything you need to build powerful templates with ease: multiple inheritance, blocks, automatic output-escaping, and much more:
Okay, so scratch that other nonsense and there might be something vaguely of interest here. Maybe. It's still unclear to me how this is supposed to be better than regular PHP OOP. But Twig should've led with this rather than with stupid strawmen.

Quote from: emanuele – Then, as side-effect, there would be the fact that becoming the templates html files, we would be forced to avoid certain things we have in the templates right now (yes, @Frenzie they are either legacy stuff or some fancy coding we did, but still with php templates it is possible to do it, while with a template engine it is not (always, or at least so heavily) possible).
They're not HTML files. You're just replacing PHP with a similar construct. :P

Quote from: emanuele – 2) we would give end-users a much more user-friendly way of dealing with template edits (i.e. no need to explain that to add a google analytics script they have to either learn a bit of php or install an addon that may or may not work because "someone" forgot to update it xD).
That's a non-argument. So you have to learn ten Twig commands instead of ten PHP commands. :) [1]

Quote from: emanuele – As far as I can see, Mustache would instead mean a one-time-full-rewrite of the whole template, that may also require some considerable work on the backend to provide exactly what we need to display (since we nowadays do quite a bit of fancy stuff in the templates).
It sounds like refactoring the code to use proper separation of concerns as if something like Mustache were involved may not be a bad idea. Cf. https://fuelphp.com/docs/general/views.html and https://fuelphp.com/docs/general/presenters.html But this can never be used as an argument in favor of a template engine.

Ignoring any arguments that are architectural in nature, it would seem that we're left with these two arguments in favor of a template engine:

  • Supposedly easier.
  • Reusable in JS.

I reject the first argument. What's this supposed to be exactly?
Code: [Select]
{{#wrapped}}
  {{name}} is awesome.
{{/wrapped}}
Oh right, I think it's equivalent to this:
Code: [Select]
<?php foreach($wrapped as $name): ?>
I'm sure users will greatly appreciate the increased clarity. :o  :(

That leaves the reusable in JS argument. The question is, does it matter? On the one hand you're probably shaving off a few bytes by using JSON, on the other hand the browser needs to do some extremely slow templating nonsense.[2] My instinct says it's probably a counterproductive battery usurper but benchmarks can easily prove me wrong.
In fact I'd argue it's more effort. You have to learn this new Twig thing instead of being able to apply your Wordpress/Magento/etc. template knowledge.
Possibly slightly faster with the Mustache drop-in Handlebars, but then again it's orders of magnitude larger.

Re: 2.0: mustache template engine?

Reply #5

@Frenzie : yes ... twig, smarty and most of the other template engines are complex and just another syntax for PHP code at all. I wouldn't use any of them...

But that's not the case with Mustache.. the logic (some special cases) would have to be moved to the controller.

Another example, taken from ElkArte code:
Code: [Select]
	// Is the clock ticking?
if (!empty($context['poll']['expire_time']))
echo '
<p>
<strong>', ($context['poll']['is_expired'] ? $txt['poll_expired_on'] : $txt['poll_expires_on']), ':</strong> ', $context['poll']['expire_time'], '
</p>';

            
in mustache.php you could do it that way:
Code: [Select]
{{#context.poll.is_expired}}
<p>
<strong>{{txt.poll.expires_on}}:</strong> {{context.poll.expire_time}}
</p>
{{/context.poll.is_expired}}
   
another approach would be
Code: (controller.php) [Select]
// poll expired? let's show a small warning
if ($context['poll']['is_expired'])
echo $mustache->render($render_data, 'poll_expired');

and
Code: (poll_expired.html) [Select]
<p>
<strong>{{txt.poll.expires_on}}:</strong> {{context.poll.expire_time}}
</p>

I think both versions are easier to read compared to the original ElkArte code..

If you look at the more complex templates, espacially those with mixed HTML, PHP and Javscript:
Code: [Select]
	if (!empty($context['attachments']['ila_enabled']))
{
addInlineJavascript('
var IlaDropEvents = {
UploadSuccess: function($button, data) {
var inlineAttach = ElkInlineAttachments(\'#postAttachment2,#postAttachment\', \'' . $context['post_box_name'] . '\', {
trigger: $(\'<div class="share icon i-share" />\')
});
inlineAttach.addInterface($button, data.attachid);
},
RemoveSuccess: function(attachid) {
var inlineAttach = ElkInlineAttachments(\'#postAttachment2,#postAttachment\', \'' . $context['post_box_name'] . '\', {
trigger: $(\'<div class="share icon i-share" />\')
});
inlineAttach.removeAttach(attachid);
}
};', true);
}
IMHO that code is readable for a skilled developer but not for an average designer, typical problems here:
where do I use  single quotes / double quotes?
where do I need to escape a quote with a backslash?

Another possible case:
Let's assume our controller would just give you JSON data. You could render that code on the server side (with mustache.php) and also on the client side, for example inside an android or IOS app (JS version of mustache) by using the exact same templates.
 

Last Edit: November 13, 2017, 05:14:28 am by TE
Thorsten "TE" Eurich
------------------------

Re: 2.0: mustache template engine?

Reply #6

I have long used a Twig in one of my modules (smf2).
Sorry for my English

Re: 2.0: mustache template engine?

Reply #7

Quote from: TE – in mustache.php you could do it that way:
Which is absolutely terrible as far as I'm concerned. I think it's an incomprehensible illegible monstrosity. I take back what I said about it looking harmless.

Code: [Select]
{{#items}} // this is foreach
  {{#first}} // this is if?! this isn't logic-less, this is logic-unclear
    <li><strong>{{name}}</strong></li>
  {{/first}}
  {{#link}}
    <li><a href="{{url}}">{{name}}</a></li>
  {{/link}}
{{/items}}

Quote from: TE – I think both versions are easier to read compared to the original ElkArte code..
Mostly true, but irrelevant.

Quote from: TE – IMHO that code is readable for a skilled developer but not for an average designer, typical problems here:
where do I use  single quotes / double quotes?
where do I need to escape a quote with a backslash?
Entirely true, yet also entirely irrelevant.

Quote from: TE – Let's assume our controller would just give you JSON data. You could render that code on the server side (with mustache.php) and also on the client side, for example inside an android or IOS app (JS version of mustache) by using the exact same templates.
Whether this would be in any way beneficial is what has to be proven. You can't presuppose that it's somehow magically useful to use "the exact same templates." That just sounds like adding extra complexity on the client side and wasting a lot of battery life by short-cutting the highly optimized HTML parser. Using different templates could potentially be worthy of the wasteful trade-off.

You can't use current Elkarte code as an argument. You have to imagine the Elk template controller and view code as if it were written for Mustache. A concrete example of a ViewModel implementation that I already mentioned can be seen in https://fuelphp.com/docs/general/views.html and https://fuelphp.com/docs/general/presenters.html

Re: 2.0: mustache template engine?

Reply #8

Answering only a quote because I'm late for work. :P

Quote from: Frenzie –
Quote from: emanuele – 2) we would give end-users a much more user-friendly way of dealing with template edits (i.e. no need to explain that to add a google analytics script they have to either learn a bit of php or install an addon that may or may not work because "someone" forgot to update it xD).
That's a non-argument. So you have to learn ten Twig commands instead of ten PHP commands. :) [1]
Sort of, my point is that to do any tweak to a template nowadays you at least to learn the specifics of "echo", this is a mandatory requirement. Yes, you can argue that is just double and single quotes, fine. I can tell you that, from my support experience, this is far more than the average admin wants to learn.
I'm not talking about designers here, I'm pretty sure designers can learne pretty much whatever language they want (if they understand bootstrap I'm pretty sure they can).

On top of that, any error in the writing of a simple tweak results in the crash of the forum (or at least part of it, but since 99% of the edits people want to do are done in index.tempalte.php, it means full crash).
With a template engine, this risk should be reduced quite a lot.

The comparison with wordpress is slightly less evident, because WP uses a completely different approach (i.e. html-with-php-injected VS php-echo'ing-html), that per se is kind of easier to grasp for the average user, but that for my personal point of view is something that makes my eyes spill blood.
In fact I'd argue it's more effort. You have to learn this new Twig thing instead of being able to apply your Wordpress/Magento/etc. template knowledge.
Bugs creator.
Features destroyer.
Template killer.

Re: 2.0: mustache template engine?

Reply #9

Quote from: emanuele – The comparison with wordpress is slightly less evident, because WP uses a completely different approach (i.e. html-with-php-injected VS php-echo'ing-html), that per se is kind of easier to grasp for the average user, but that for my personal point of view is something that makes my eyes spill blood.
You can write Wordpress templates "Elk style" if you prefer as well, though really doing so is just more difficult and less clear. But why does the "Wordpress style" offend you? The alternative is just "replacing PHP with a similar construct" to quote what I wrote a few hours ago. {{ var }}[1] may or may not look superficially vaguely more attractive than something like <?php echo $var; ?> but what difference does it actually make? I'm not particularly convinced one is clearer than the other either — a much more important metric, I might add. If you truly dislike that style so badly for some reason then yes, perhaps something that compiles down to <?php echo $var; ?> is better. But it doesn't sound like a very good argument.[2]

Incidentally, I think this is quite elegant: https://github.com/tropotek/tk-domtemplate

In any case, the point is that showing some complex thing full of commas and quoting difficulties and ternary operators in order to present a template engine as an alternative to that is deceptive toward yourself and others. It's just not a fair comparison. You can do the same rewrite with the same separation of concerns without adding anything extra.

QuoteOn top of that, any error in the writing of a simple tweak results in the crash of the forum (or at least part of it, but since 99% of the edits people want to do are done in index.tempalte.php, it means full crash).
With a template engine, this risk should be reduced quite a lot.
An interesting point.
Fun fact: you can change the Mustache delimiters to make it look like <?php var ?> to annoy you. :P
To be clear, I completely agree. I kind of dislike PHP and seeing it in HTML like that is an unpleasant sight, although from… 5.3 or so, maybe 5.5 and up it's not so bad. But the answer to my "problem" is to use a different language entirely, not to use something else on top of PHP. :P

Re: 2.0: mustache template engine?

Reply #10

Btw, there's also http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc

That way you can

Code: [Select]
echo <<<HTML
no " quote ' escaping necessary lalala $var

and because we used HTML we get the correct highlighting in Vim!

No logic allowed in here either.
HTML;

Re: 2.0: mustache template engine?

Reply #11

Quote from: Frenzie – But why does the "Wordpress style" offend you?
Because my brain is too simple, last time I tried to enter-php(conditional)/exit-php(bloc-in-the-conditional)/enter-php(second-optiona-of-the-conditional)/exit-php(some-html)-enter-php(start-loop)/exit-php(bits-of-html-for-theloop)/enter-php(echo-var)/etc. my brain gave up and shutdown. xD
I'm not able to follow a slightly-more-than-basic conditional/loop in the WP-like style (and that's one of the reasons I abandoned almost completely the software).

But I guess that's mostly an holy-war like it could be tab-VS-spaces and curly-on-the-same-like-VS-curly-on-the-next-line. ;D

That said, I'm not trying to defend Elk-styling, because I don't like that one either: two levels of indentation (one for php code, one for html markup), quite complex logic structures, function calls (and even closures I think) and so on.

I'm open to alternatives, in order to find something that:
1) is not too difficult to understand and learn,
2) is easy on end-users (not talking about themes) not generating hard failures,
3) (that is more 2b) does not require executable files in the template directory,
4) is not too complex to implement,
5) is maintained (for two reasons: a) have a fast reaction to potential security issues and b) no need to write our own template engine when the only advantage we'd have is to have more code to maintain).

Then, of course, point 1 and 2 are subjective (and point 4 depends on the skills and knowledge of the one that is going to implement it, so it's kind of subjective as well).

Based on my objectives, almost any template engine is to me preferable to php code because of point 2 (and 3), then, which one in particular is just a matter of discussion.
Of course, that's just my own opinion and not much more, if others prefer not to use a template engine at all, fine.

Interesting indeed. :D
Bugs creator.
Features destroyer.
Template killer.

Re: 2.0: mustache template engine?

Reply #12

I'm fine with a template engine really, whichever out of e.g. Smarty, Twig[1] or Mustache (not RainTPL anymore; it's dead), maybe others. The benefit is much the same regardless whether you implement the better separation of concerns with or without a special template engine, but it's an improvement in maintainability, comprehensibility and convenience either way. It would be counterproductive to oppose that, especially if it means the situation would otherwise remain as it is. ;)

Smarty has clever template inheritance. Mustache only has unofficial extensions that are mutually incompatible.[2] I'm also not sure if it's quite as clever, but it's probably good enough.
Although I now really do severely dislike its use of strawman arguments.
The PHP Mustache implementation seems to be somewhat Twig-inspired.

Re: 2.0: mustache template engine?

Reply #13

Not being a coder and no nothing about php I think a template system would great for people like me that makes themes and know nothing about coding.

Re: 2.0: mustache template engine?

Reply #14

I'm not sure what this buys other than another dependence on a third party project and whatever limitations it enforces and yet more files that have to be edited /searched to make a change.  All the ifs, elses, and variable setting has to happen anyway.  If you don't want to break up your echo statements do all the work you'd have to do for the template engine above the echo then just write the echo with variable names.

echo '
<html stuff>${variable_name}<more html stuff>
';

No splits, indent how you want, etc.  If it's complicated enough to need split up for lots of if / else branches that totally change the rendering that's all still true for the template too right?