Voir cette page en français

Jul 09 2011

Efficient HTML code generation without templating system

Category: Divers ,PHP


Summary

The purpose of this paper is to show that in the context of a professional web development (in PHP in this case but it remains valid for other languages​​) the use of a good HTML generator is better than templating system. After an overview of existing solutions of HTML generators we will see that there is, in my opinion, nothing very convincing ; I therefore propose a PHP class, based on an original idea by Jean-François Gigand, which allows you to generate your HTML pages in a simple, efficient, robust, readable and fast way using the chaining coding style.

If you hurry, you can go directly to the presentation of XmlTag.

Why templating systems in PHP are they harmful ?

In short, in case you have not yet realized, PHP is already a templating system, so it is completely unnecessary to add an additional templating system. If you are not yet convinced, here are some links that explain in more detail why the addition of a templating system in PHP is bad :

Why all web templating system should be avoided ?

I go further, affirming that all web templating systems (including native PHP templating) often give unreadable codes, difficult to maintain and so unprofessional. Here's a simplified example, generally it is often worse, extract from a WordPress theme where I deleted indentations because none of IDE that I know indents correctly this kind of ugly code :

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<div <?php post_class(); ?> id="post-<?php the_ID(); ?>">
<?php if($show_date) :
$time = get_the_time(_c('M d Y|Dates','stardust')); ?>
<div class="date" title="<?php the_time(_c('d-m-Y|Dates','stardust')); ?>">
<p><span class="mese"><?php echo($mo); ?></span></p></div><?php endif; ?>
<h2 class="storytitle"><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></h2>
<div class="meta"><span class="tags"><?php _e("Category:"); ?>
<?php the_category(',') ?></span> &#8212; <span class="user">
<?php the_author() ?> @ <?php the_time() ?></span> <?php edit_post_link(__('Edit This')); ?></div>
<div class="storycontent">
<?php if (function_exists('the_tags')): ?>
<p class="meta"><?php the_tags(__('Tags: ').' ',', '); ?></p>
<?php endif;?>
</div>
<div class="feedback">
<?php wp_link_pages(); ?>
<p><?php comments_popup_link(__('Comments (0)'), __('Comments (1)'), __('Comments (%)')); ?></p>
</div>
</div>
<?php endwhile; else: ?>
<p><?php _e('Sorry, no posts matched your criteria.'); ?></p>
<?php endif; ?>
  

How do I know if the code HTML is valid ?
How follow the logic of the layout ?
How to easily find the closure of a condition, a loop ?
How to get to a matching closed/opened tag ?

Unfortunately, it's how most PHP developers learn to code their views and impose to others the maintenance of such boiled shapeless, sometimes decorated by Javascript code which dynamically turns to modify the DOM… A pleasure to maintain this kind of code, and I unfortunately know what I mean…

HTML Generators, State of the Art

Some PHP classes exist that allow to generate the code HTML directly from PHP, without templating system like what is done in Python with WebHelpers (moreover not perfect at all) :

  • phpHtmlLib : I've never used it but it is clear that it is not intuitive to use and, looking at the source code, I have reservations about its performance. It seems to be however the best of my list
  • the html helpers of CakePHP show a very clumsy design methods (in fact all CakePHP is clumsy and poorly designed. To be used for 10 months I will explain in another article why do not use CakePHP on serious projects). So, with the class HtmlHelper of the poor CakePHP this is the kind of code we get:
          echo $this->Html->tag('div',
              $this->Html->tag('span',
                  $this->Html->tag('strong', 'Hello world', null),
              array('class' => 'hello')),
          array('class' => 'welcome')
          );
          
    To change the class of the first div you have to cross the whole HTML tree and change the "array" at the end of the code, it's hilarious, it's CakePHP in all his splendor…
  • the HTML Helper of CodeIgniter seems to be a work in progress. On the other hand, do heading('Welcome!', 3); to obtain <h3>Welcome!</h3> has no interest, no meaning and the concept "one function for one tag" does not please me at all, especially since the functions do not always have the same name as the tag (link_tag, h1 as example)…
  • the project php-html-generator is based on the principle « on class = one tag » and you obtain this kind of code :
          $div = new Div('abc');
          $div->addInner(new Span('a', new label('x', 'Labão')));
          $div->addInner(new Span('v', 'ancv'));
          $div->addInner(new Span('c', 'ancc'));
          
    The code is far too wordy and it lack of clarity !
    Using addInner all the time do not permit to see the nesting by indentation, the code thus lacks clarity. I have not tested everything but I do not want looking at the rest…
  • HTML Generator : there is a function to open the tag and one to close it… when I think I signed up to see such nonsense
  • I stop the killing there…

XmlTag : a simple, efficient, robust and readable HTML/XML code generation

Following all the above considerations, this is the class I propose ; it can generate HTML/XML with a clean, readable, and optimized code directly in PHP hardcore. Thus the following HTML

<p>
  <strong>du gras ici,</strong> <i>de l'italique ici</i>
</p>
<div class="ma_super_classe" id="leZId">
  du texte concaténé avec <span style="color:red"><i>de l'italique rouge</i></span>
</div>
<div>
  <p>
    Encore un pour la route
  </p>
</div><br />

  
…is obtained by the following PHP code :
$xmlTag
->P($xmlTag()
    ->STRONG('du gras ici, ')->I('de l\'italique ici')
)
->DIV(array(
        'class' => 'ma_super_classe',
        'id' => 'leZId',
    ), $xmlTag('du texte concaténé avec ')
    ->SPAN(array('style' => 'color:red'), $xmlTag()
        ->I('de l\'italique rouge')
    )
)
->DIV($xmlTag()
    ->P('Encore un pour la route'))
->BR();

echo $xmlTag;

  

In fact we get a HTML code optimized on a single line, but in development phase, we can apply a filter Tidy which indents the HTML code to make it more readable, as I did here.

The Advantages of XmlTag

  • no need to learn a new language of templating ;
  • xmlTag is more faster then any external templating system ;
  • the code is readable, even by a web designer allergic to programing ;
  • we are sure that the HTML generated is valid  ; it is impossible to forget a closing tag or close the tags in the wrong order ;
  • the PHP code is always correctly indented, whatever the IDE that we use ;
  • we can navigate very quickly the code structure using parentheses matching ; is a feature present in all IDE ;
  • the generated HTML code is optimized, no need to go through a solution such as those proposed at the end of this page.

Documentation

For further information, please refer to the complete examples of using the class XmlTag

Download XmlTag