mustache

In Search for Template Reuse Between Angular.js and PHP

PHP itself is a great templating engine. No doubts. Why to add another overhead? From my perspective is the reuse between back-end and front-end. Why is there need to produce same code on server? Few of my concerns: SEO, usability (fallback for no-javascript on old devices)

Language diferences for building any web apps:

  • on client: HTML + CSS + Javascript
  • on server: HTML + CSS + PHP (or any language of your choice like Ruby, Pyton, Java, ASP,…)

If you are lucky, your host supports Node.js and reuse of templates is very doable. But most of the time you can consider yourself lucky when your host is running latest PHP codebase.

For the lucky ones try:

Options for the rest of us

I personally went down the {{ mustache }} way. There plenty of ports supported, with mature JS and PHP in the gang.

As I see it, there’s quite big chance of reusing same partials within the Javascript client app and server-side PHP version. Maybe not that perfect, but since there’s need for two code bases for the same app (server in PHP and Javascript on client) including same portions of templates is a nice jump start.

If you’ve tried other options, please share your experience in the comments

In the meantime: Here comes Angular.JS

Quite frankly there’s quite much hype around the Angular.JS project. Many consider Angular the future of the webapps.

Recently, Angular.JS based framework for developing hybrid mobile apps with HTML5 went from experimental to beta.

Yay, great news. Since Ionic uses Cordova you can now build better experiences for iOS, Android (and other platforms) in the same time.

Let’s face it. Supporting PHP based website, Angular.JS based webapp (thanks to Ionic also major app stores of Apple, Google or Windows), still there is 2 (and some extra bits bridging extras to webview) different cobases.

Diferences between Mustache and Angular.js, PHP templating

Since Mustache supports only minimal logic in templates I’ll use it as the base for my comparison.

Displaying value of variable

  • Mustache: {{ someValue }}
  • Angular: {{ someValue }} (or <span ng-bind="someValue"></span>)
  • PHP: <?= $someValue ?> (or <?php echo $someValue; ?> <?=?> is not supported)

The diference is fairly similar for Mustache and Angular.JS. Even generating mustache/Angular.JS compatible string is possible. Here’s a very simplified example:

function transcript_php_to_js($str) {
    return strtr(
        array(
            '<?=' => '{{',
            '?>'  => '}}',
            '$'   => ''
       ), $str
    );
}

Loops

In Mustache:

<ul>
    <li class="extra">We can have manually inserted items here.</li>
    {{ #items }}
    <li>{{ . }}</li>
    {{ /items }}
</ul>

In Angular.JS:

<ul ng-repeat-start="item in items">
    <li>{{ item }}</li>
</ul>

In PHP:

<ul>
    <li class="extra">We can have manually inserted items here.</li>
    <?php foreach ($items as $item): ?>
    <li><?=$item?></li>
    <?php endforeach; ?>
</ul>

You can still spot similarities, but there’s a but. Mustache is fairly similar to PHP’s using opening and closing sections of the loop, where as Angular.JS uses only ng-repeat attribute on the opening tag.

I’ve also added an extra list item to the Mustache and PHP versions for you to understand that there’s a big incompatibility with the ng-repeat. Angular simply will not produce any list item outside of the scope (context in the Mustache terminology, function scope in PHP’s).

Since use of Angular.JS on the client would be a must let’s see our options to transcript Mustache and PHP to Angular template. From transcript would not be possible without a change in the mindset (using loops as Angular.JS would) or with dev familiar with the Angular.JS’s output (overwritten extras in the ng-repeat results.

It’s getting more complicated.

Use of Angular.js templates as the base is therefore much more straightforward as vice-versa. PHP/Mustache to Angular.JS would involve using a DOM parser to find the parent element (or other methods).

Wait a sec. We’re talking reuse here. Use of this template for Mustache is still perfectly OK:

<ul ng-repeat-start="item in items">
    <li class="extra">We can have manually inserted items here.</li>
    {{ #items }}
    <li>{{ . }}</li>
    {{ /items }}
</ul>

Producing the Angular.JS template would be easy as removing the opening and closing Mustache tags. The extra list item is of course a problem here as it would be repeated on client too. (Mindset change is required or removal of the extra line, which would be harder to properly detect.)

Same for PHP without the extra line:

<ul ng-repeat-start="item in items">
    <?php foreach ($items as $item): ?>
    <li><?=$item?></li>
    <?php endforeach; ?>
</ul>

Than the function efectively removing the code between <?php and ?> tags could look a litle like this:

function transcript_php_to_js($str) {
    return strtr(
        array(
            '<?=' => '{{',
            '?>'  => '}}',
            '$'   => ''
        ),
        preg_replace(
            '/ *?<\?php.*?\?>\n?/',
            '',
            $str
        )
    );
}

Logicless

As you can see, there are possibilities of reuse of Mustache and PHP templates for the Angular.js web apps.

Using only PHP version you, however, need to consider the following:

  • forced decoupling of template logic and business logic in Mustache is beneficial in the long term perspective
  • complicated conditional sections are not transcriptable easily even though Angular provides ngSwitch or ngIf
  • having a logic-less habit similar to Mustache is beneficial

Since Mustache can be cached as PHP files that are being than included, the performance to native PHP templating might not be a concern. Therefore I am thinking about the Mustache to Angular transcription as a way to go.

What are your thoughts about it? Say it in the comments below.

  • Christopher Thomas

    I found this project on github and I thought it looked promising, I also was interested in this because if you want to render pages for SEO purposes, for googlebot then you have to return a completed page, but angular will render everything using javascript.

    https://github.com/esvit/php-angular

    in 2012-13, here was the way that people got around the blank javascript controlled page rendering

    http://www.yearofmoo.com/2012/11/angularjs-and-seo.html

    another article, seemingly saying the same thing

    http://www.ng-newsletter.com/posts/serious-angular-seo.html

    now I realise that you’d have to duplicate the logic which composed all the templates together, but this might be significantly easier if you could render the angular templates in PHP and use those escaped fragment commands to direct to a separate/hidden php website which would reuse what it can whilst allowing angular to do it’s thing unchanged.

    I’m not sure whether the php-angular project supports everything you can do in angular, I’m just glad I found it and your article at the same time, so I thought to post this to let people know about what I found.

  • Sorry @disqus_MvlKJWBGGr:disqus , your comment got lost in the Disqus moderation. By the time I came-up with some other approach, totally leaving the Angular.JS to PHP render approach.

    See http://www.martinadamko.sk/posts/220

    The header image is a real GIF snapshot of my latest project. All the data is loaded in the background and the website’s speed can be perceived as crazy fast.

    I would be interested to know what you think of it.