This article is archived, which means it may not be current and I can't answer questions about it. Some readers may still find it useful, though.

Roll Your Own HTML Templates With PHP

HTML is not a programming language. But it only takes one look at a complex HTML document to realize that it is code, in some cases impenetrable code.

Somewhat paradoxically, HTML can be made easier to work with by using some of the features of a full-fledged programming language. This article will describe a method that uses basic features of PHP to make HTML code more readable and reusable. For HTML authors without any formal training in computer science, it introduces classic structured programming techniques and applies them to web documents.

To use the method shown here, you will need a web server that runs PHP and basic coding skills.

Defining the Problem

Consider some HTML code which defines a complex table-based page layout:

<html>
<head>
  <title>Complex table layout example</title>
  <style type="text/css">
    html, body {
      height: 100%;
      margin: 0;
      padding: 0;
      border: none;
    }
    #full { height: 100%; }
  </style>
</head>
<body>
<table bgcolor="#7777aa" width="100%" border="0" 
  cellspacing="0" cellpadding="0">
  <tr>
    <td><h1>Complex table layout example</h1></td>
  </tr>
</table>
<table width="100%" border="0" cellspacing="0" 
  cellpadding="0" id="full">
  <tr valign="top">
    <td nowrap bgcolor="#d0d0d0" width="125px">
             Menu a
<br/><a href="item1">Item 1</a>
<br/><a href="item2">Item 2</a>
<br/>
<br/>Menu b
<br/><a href="item1b">Item 1</a>
<br/><a href="item2b">Item 1</a>
    </td>
    <td>
      <p>
         This is the main content. Alice was beginning to get
         very tired. It was a dark and stormy night. Call me
         Ishmael.
    </td>
    <td nowrap bgcolor="#e0e0e0" width="75px">
     <a href="http://example1.com/">Link 1</a>
<br/><a href="http://example2.com/">Link 2</a>
<br/><a href="http://example3.com/">Link 3</a>
<br/><a href="http://example4.com/">Link 4</a>
<br/><a href="http://example5.com/">Link 5</a>
<br/><a href="http://example6.com/">Link 6</a>
    </td>
  </tr>
</table>
<table width="100%" bgcolor="#d0d0d0" border="0" 
  cellspacing="0" cellpadding="0">
  <tr>
    <td><p align="center">This is the footer. (c) 2006</td>
  </tr>
</table>
</body>
</html>

You can view the page here. Although this page is much simpler than many real-world examples, it is already difficult to read. Interestingly, the structure of the overall document is fairly simple, but the presentation of too many complex details all at once makes that difficult to see. If the code is rewritten to present the document structure clearly, it will become more maintainable.

HTML Subroutines

One of the basic organizing features of any good programming language is the subroutine. If we had an HTML subroutine, we could use top-down design to better structure the complex table layout. So where to look? An obvious candidate for an HTML subroutine is a PHP function. For example, consider the fragment of HTML which defines the page header:

<table bgcolor="#7777aa" width="100%" border="0" 
  cellspacing="0" cellpadding="0">
  <tr>
    <td><h1>Complex table layout example</h1></td>
  </tr>
</table>

Using PHP functions, we could write this as

function header()
{
?>
  <table bgcolor="#7777aa" width="100%" border="0" 
    cellspacing="0" cellpadding="0">
    <tr>
      <td><h1>Complex table layout example</h1></td>
    </tr>
  </table>
<?php
}

However, a primary goal of this technique is readability, and switching back and forth between PHP and HTML hurts the readability of this code fragment. It's also inflexible to write a function that echoes output immediately when called. We want a flexible technique that allows us to set up some HTML and use it whenever we need it. And finally, this technique doesn't offer an obvious way to nest subroutines.

A better approach uses another feature of PHP called "here documents." Using this technique the code would be written:

$header = <<< EOF
  <table bgcolor="#7777aa" width="100%" border="0" 
    cellspacing="0" cellpadding="0">
    <tr>
      <td><h1>Complex table layout example</h1></td>
    </tr>
  </table>
EOF;

The effect of this code fragment is to set the variable $header equal to the HTML code between the first and second "EOF". Then the variable can be reused or printed anywhere it's needed.

An important feature of here documents is that variable substitution occurs within them. As a result, a subroutine can be nested by including a variable in another variable definition. This feature comes with a warning: because variable substitution is performed in here documents, the dollar sign is a special character. If you want a literal dollar sign you have to escape it by preceding it with a backslash. With the exception of this rule, you can continue to write exactly the same kind of HTML that you would use in a plain HTML file.

A Top-down Approach

Now that we have a good HTML subroutine, we can analyze the whole page into logical pieces and then reassemble them. Taking a top-down approach, the page as a whole will look like this:

$html = <<< EOF
  <html>
  <head>
    <title>{$title}</title>
    {$style}
  </head>
  <body>
    {$header}
    {$mainbody}
    {$footer}
  </body>
  </html>
EOF;

As you can see, the whole structure of the page is revealed at a glance. Completing the document is simply a matter of defining values for $title, $mainbody, $footer, and $style.

The footer:

$footer = <<< EOF
  <table width="100%" bgcolor="#d0d0d0" border="0" 
    cellspacing="0" cellpadding="0">
    <tr>
      <td><p align="center">This is the footer. (c) 2006</td>
    </tr>
  </table>
EOF;

The style:

$style = <<< EOF
  <style type="text/css">
    html, body {
      height: 100%;
      margin: 0;
      padding: 0;
      border: none;
    }
    #full { height: 100%; }
  </style>
EOF;

The main body of the document, stored in the variable $mainbody, calls three other HTML subroutines:

$mainbody = <<< EOF
  <table width="100%" border="0" cellspacing="0" cellpadding="0" 
    id="full">
    <tr valign="top">
      <td nowrap bgcolor="#d0d0d0" width="125px">
        {$leftcolumn}
      </td>
      <td>
        {$content}
      </td>
      <td nowrap bgcolor="#e0e0e0" width="75px">
        {$rightcolumn}
      </td>
    </tr>
  </table>
EOF;

Here again the use of subroutines helps reveal the structure of the document, making it much easier to edit the table to make layout changes, for example.

The remaining code fragments are straightforward. The left column:

$leftcolumn = <<< EOF
  Menu a
  <br/><a href="item1">Item 1</a>
  <br/><a href="item2">Item 2</a>
  <br/>
  <br/>Menu b
  <br/><a href="item1b">Item 1</a>
  <br/><a href="item2b">Item 1</a>
EOF;

The content:

$content = <<< EOF
  <p>
    This is the main content. Alice was beginning to get very
    tired. It was a dark and stormy night. Call me Ishmael.
EOF;

The right column:

$rightcolumn = <<< EOF
       <a href="http://example1.com/">Link 1</a>
  <br/><a href="http://example2.com/">Link 2</a>
  <br/><a href="http://example3.com/">Link 3</a>
  <br/><a href="http://example4.com/">Link 4</a>
  <br/><a href="http://example5.com/">Link 5</a>
  <br/><a href="http://example6.com/">Link 6</a>
EOF;

And the title:

$title = "Complex table layout example";

That completes the document. If you use this technique, remember to define the basic building blocks at the top of the file and the higher-level subroutines which use them later, rather than using the top-down order which has been followed here.

The only task left is to actually print out the HTML that we have assembled:

echo $html;

Wrapping the whole thing in <php> tags and putting everything in the right order, the final document looks like this:

<?php

$title = "Complex table layout example";

$header = <<< EOF
  <table bgcolor="#7777aa" width="100%" border="0" 
    cellspacing="0" cellpadding="0">
    <tr>
      <td><h1>{$title}</h1></td>
    </tr>
  </table>
EOF;


$leftcolumn = <<< EOF
       Menu a
  <br/><a href="item1">Item 1</a>
  <br/><a href="item2">Item 2</a>
  <br/>
  <br/>Menu b
  <br/><a href="item1b">Item 1</a>
  <br/><a href="item2b">Item 1</a>
EOF;


$content = <<< EOF
  <p>
    This is the main content. Alice was beginning to get very
    tired. It was a dark and stormy night. Call me Ishmael.
EOF;


$rightcolumn = <<< EOF
       <a href="http://example1.com/">Link 1</a>
  <br/><a href="http://example2.com/">Link 2</a>
  <br/><a href="http://example3.com/">Link 3</a>
  <br/><a href="http://example4.com/">Link 4</a>
  <br/><a href="http://example5.com/">Link 5</a>
  <br/><a href="http://example6.com/">Link 6</a>
EOF;


$mainbody = <<< EOF
  <table width="100%" border="0" cellspacing="0"
    cellpadding="0" id="full">
    <tr valign="top">
      <td nowrap bgcolor="#d0d0d0" width="125px">
        {$leftcolumn}
      </td>
      <td>
        {$content}
      </td>
      <td nowrap bgcolor="#e0e0e0" width="75px">
        {$rightcolumn}
      </td>
    </tr>
  </table>
EOF;


$footer = <<< EOF
  <table width="100%" bgcolor="#d0d0d0" border="0" 
    cellspacing="0" cellpadding="0">
    <tr>
      <td><p align="center">This is the footer. (c) 2006</td>
    </tr>
  </table>
EOF;


$style = <<< EOF
  <style type="text/css">
    html, body {
      height: 100%;
      margin: 0;
      padding: 0;
      border: none;
    }
    #full { height: 100%; }
  </style>
EOF;


$html = <<< EOF
  <html>
  <head>
    <title>{$title}</title>
    {$style}
  </head>
  <body>
    {$header}
    {$mainbody}
    {$footer}
  </body>
  </html>
EOF;

echo $html;

?>

You can view the PHP version here. That's certainly a whole new look for HTML. Taking a moment to think about what has been accomplished here, we'll realize that subroutines like $mainbody and $html are high-level patterns that can be easily reused to create a great variety of documents by varying the lower-level subroutines they call.

Limitations

One problem with this technique is that it resorts to PHP, which exacts a performance hit in comparison to static HTML, simply for organizational reasons. Thus your pages load more slowly without doing anything static HTML couldn't do already. This is a good point: as a rule of thumb, static HTML can serve twice as many pages per second as PHP.

This theoretical limitation turns out to be unimportant in practice. In many cases, the web server won't be under heavy enough load for the relatively slight performance difference to matter. When it does matter, because a site becomes very popular, it is not difficult to optimize this technique by caching the dynamically generated pages as static HTML.


Copyright by Stephen Jungels. Written permission is required to repost or reprint this article

Valid HTML 4.01 Transitional

Last modified: Fri Sep 12 16:42:25 CDT 2014