Post a Blog in Response to Blog Critique of Web Template Engines

17 Apr 2019 at 17:12:54 user 'jcobban' wrote: Critique of Web Template Engines

In designing a web site an excellent structure to follow is Model/View/Controller (MVC).

An important reason for doing this is recognizing that different members of the team have different expertise and different objectives.  Another is that different languages are used for each of the components and it is undesirable to require that every member of the team is familiar with all of the languages.

  • The language used to implement dynamic functionality within a page is usually "JavaScript" as this is the only language which all browsers are required to support and which therefore comes with embedded support as a consequence of installing the browser.  If the owner of the web-site does not also have administrative control of every browser that may be used to access the web-site then there is little choice.  JavaScript does have its deficiencies from the point of view of development costs and security, but alternatives such as Java or C# can only be used within an intranet where all of the computers accessing the corporate web-site are managed by the corporation.
  • The language used to implement the View is HTML since that, including its dialects HTML4, XHTML, and HTML5, is the only language which is supported by all browsers.
  • The language used to implement the Model in the web server is flexible because it is entirely under the control of the web-site owner, and from the very beginning the only restriction which web server engines have imposed was that the application support the programming interface of the web server engine.  For example in the popular Apache server this is the Common Gateway Interface (CGI).  Corporate web-sites generally use C# (.NET) for this purpose, but most sites are implemented using an interpretive language such as Ruby or PHP.

Because PHP comes bundled as part of the Linux/Apache/MySql/PHP (LAMP) and Linux/Nginx/MySQL/PHP stacks (LEMP) which are the second and third most popular hosting platforms, PHP is the first choice for development language.  However it is trivial to add support for whatever language you prefer.  I wrote my first web-site in C++.

PHP is an interpretive language originally introduced to simplify web page development by permitting the same program to contain both logic (Model) and presentation (View).  The acronym originally stood for Personal Home Page, although now it is a recursive acronym PHP Hypertext Preprocessor.  PHP borrowed much of its syntax from the PERL scripting language which was the most popular language used to program directly to the CGI interface in the first Apache servers.  But among other issues the very fact that it mixes Model and View in a single piece of code complicates the development and maintenance of a web-site.

Using PHP requires experience in procedural languages, but complicates this because the language syntax is not derived from any predecessor procedural language, but rather from the shell scripting languages of the UNIX operating system.   The original UNIX "sh" shell scripting language begat a whole family of successor languages but the one essential feature of all of these languages is that anything that was a valid script in "sh" remains a valid script with the same meaning in all of the successors, including PERL.  And PERL's child PHP inherits this.  Indeed PHP can be used as a UNIX scripting language by inserting the appropriate shebang as the first line.  In particular comments start with a hash sign (#) and variable names in all of these languages are explicitly identified as such by starting with a dollar sign ($).  PHP then muddles that up by also requiring that the programmer be familiar with HTML.  This is a serious problem in professional web development because the person responsible for customizing the View, that is embodied in HTML, must work very closely with the end-users to ensure that the presentation serves the users.  In large organizations, particularly in government, that presentation must also comply with standards established by the organization.  The end-users are also a constantly moving target.  By contrast the logic defined in the Model changes much less frequently.  So it is highly undesirable to include both Model and View in the same source code.


A few specific examples of this which I have personally dealt with in the last few years:n
  • Not everybody in the World is fluent in English. Even within English there are major cultural divides in terms of vocabulary and style between different communities.  An English bloke who tells an American girl "I'll knock you up in the morning." will likely receive a slap.  When I looked at the traffic on my personal web-site I discovered that almost 30% of the users were from Germany.  So how do you add support for other cultural markets if the HTML is embedded in the logic?
  • The standards for web style are constantly changing.  Before CSS the only way to control the positioning of components on a web-page was by use of tables.  But tables create problems for users of adaptive technologies for support of the differently-abled.  Furthermore when I started my personal web-site the state of the art was to include a list of nodes on each page delineating where the current page was located within the hierarchical structure of the site, and to have other links on the page to services that the user might need, such as contacting the author of the page or viewing documentation.  However more recently most web-sites are used by devices which have small displays. Tieing up "real-estate" on the page for information which the customer "might" need is too costly.  So menus and other service links are hidden until the user requests to see what is available to do.
  • Corporate style changes require that every page on the web-site be changed to maintain the common appearance.

So PHP encourages bad habits.  Some of the newer languages which have been spawned off from PHP such as the Hack language, developed by Facebook to implement its website and to improve programmer productivity and web-site performance, have removed the ability to imbed HTML within a PHP program.

To address the separation of Model and View it is necessary to use a template engine.  There are a lot of choices here because this problem has been encountered by a lot of development teams over the years.

        <title>My Webpage</title>
        <ul id="navigation">
        {% for item in navigation %}
            <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
        {% endfor %}

        <h1>My Webpage</h1>
        {{ a_variable }}

This is popular but it includes logic, the for loop, in what is otherwise an HTML document.  Similarly Smarty also incorporates logic into the HTML.

{foreach $names as $name}
   <tr bgcolor="{cycle values="#eeeeee,#dddddd"}">

{foreach $users as $user}
   <tr bgcolor="{cycle values="#aaaaaa,#bbbbbb"}">
Also the Blade template language used in Laravel mixes logic with presentation:

@foreach ($users as $user) <p>This is user {{ $user->id }}</p> @endforeach

My requirement was therefore to completely separate logic and presentation so that the web-page designer did not have to learn another language in addition to HTML and CSS.  So the template engine I created, which you can see on GitHub, uses pure HTML except for specifying where information from the server is to be inserted into the page.  For example the master template for the common portions of a page on my personal web-site is

This is a pure HTML file except for the insertion points which start with a dollar sign.   This insertion syntax is modelled on the string syntax of PERL and PHP.  The template engine also supports a syntax like that of Twig and Blade where the insertion point names are enclosed in double braces, but you cannot mix both styles in a single template.

The logic used to insert information from the server into the template supports two styles:
  • Simple substitutions: $template->set('USERID', $userid) where the named insertion point is replaced by the value.
  • Document Object Model (DOM) based substitutions in which the logic describes how an HTML tag, which is identified by its id attribute, is to be modified.  $template['otherStylesheets']->update(array('filename' => $filename))  specifies that the tag with id='otherStylesheets' is to be modified by replacing the substitution point $filename with the supplied value.  If the value passed to the update method is an array of associative arrays then multiple copies of the tag are generated, for example to create multiple rows of a table, or multiple options in a select statement, or in the case of this specific template multiple link statements for multiple CSS files.  If it is a string the entire tag is replaced by that string.  If it is null or an empty array the entire tag is deleted.  So the script programmer responsible for the Model implements the functionality which in other template engines is performed by special language artefacts in the template.  The DOM as implemented by the template engine supports a number of methods modelled on JavaScript.  For example $template->getElementById($id) is the full call for which $template[$id] is a short form.  Once you have a tag you can get the parentNode(), loop through the childNodes(), get the outerHTML() or the innerHTML(), and getElementsByTagName(). 

The substitution $MAIN in the above template is a special case, but only because of how it is used by the PHP logic. It is replaced by an application specific template identified by $template->includeSub($filename, 'MAIN').  This insertion is done before any of the other substitutions because the template itself is not complete until the application specific portion is inserted.   
To see this in action go to Benjamin John Harrison (24 Apr 1861—1931). Click on the menu button and you will see options to view this page in Francais and Deutsch.  Choose those options to see how simply changing the version of the template alters what is presented to the user.

For further details see the Programming Guide on GitHub.

Follow up:

This field supplies a title or a summary of the content of the blog If this is omitted the first line of the body of the message is used as subject.
Ce champ permet de modifier un message à publier en tant qu’entrée de blogue.
Si vous n'êtes pas connecté en tant que contributeur inscrit au site Web, vous devez fournir une adresse e-mail pour identifier la source de tout messages de blogue que vous publiez. Cette adresse e-mail sera exposée dans le message posté.
Cliquez sur ce bouton pour poster le message que vous avez entré. L'application prend également en charge le raccourci clavier Alt-B.