Template System

My website's layout & design is completely abstracted from the content. The layout is contained in a single file, which may be easily replaced by another layout and the change will automatically be reflected across all the pages which utilize that layout. Here I will demonstrate how it works.

To start with, there are two primary functions, named starttemplate and stoptemplate. They are contained in a file named template.php which is included at the top of every page on this site.

The function starttemplate takes two parameters, the first one tells the template engine which layout file to use (there may be multiple layouts to chose from), and the second one is an associative array (hash) which contains variables for the layout such as the title and description for the page.

starttemplate is called immediately after including template.php. Then the page's content follows. At the end of the page, stoptemplate is called, which finishes the job.

This is what a sample page would look like which uses the template engine. Let's call this sample_page.php:

sample_page.php

<?php
 include('template.php');
 starttemplate('default',
       array('TITLE'=>"a title",
       'DESCRIPTION'=>"a description"));
?>

blahblahblah... content goes here.<br>

<?php
 stoptemplate();
?>


As you can see this greatly simplifies the page. Now, there is nothing in the page which describes the layout.

Here is template.php, the part that does all the work:

template.php

<?php

 // A simple template engine.
 // (c) 2004 Jayson King.

 function starttemplate($template, $pageinfo) {
  global $pagelayout;
  ob_start();
  include('template-'.$template.'.php');
  $pagelayout = ob_get_contents();
  ob_end_clean();
  while(list($key, $val) = each($pageinfo)) {
   $pagelayout = ereg_replace('{'.$key.'}', $val, $pagelayout);
  }
  ob_start();
 }
 function stoptemplate() {
  global $pagelayout;
  $newcontent = ob_get_contents();
  ob_end_clean();
  $pagelayout = ereg_replace('{CONTENT}', $newcontent, $pagelayout);
  echo $pagelayout;
 }
?>


starttemplate first declares $pagelayout as a global, since it will need to be available in stoptemplate. Then it starts an output buffer which will be used to collect the contents of the layout (I chose to do it this way so that the layout may contain not only HTML but also some PHP which may output dynamic content. This is more flexible than simply opening and reading a pure HTML layout).

Then the layout file is included. Layout filenames start with 'template-' to differentiate them from other files, and also to prevent other files from being mixed in and treated as layout files.

After the layout is included, the contents of the buffer are fetched and stored in $pagelayout. Then the buffer is cleared.

Then there is a while loop which replaces certain keywords in the layout with those values found in the hash. For example, {TITLE} is replaced by the title that was specified in the hash.

After all of that, a new output buffer is opened that will collect the page's content.

As for stoptemplate, all it does is fetch the contents of the buffer last opened by starttemplate, and puts it in place of {CONTENT} in the layout, then echos the whole thing to the client.

And here is what a layout file would look like. It is mostly a normal HTML file (but which may also contain PHP) and has some variable placeholders. Let's call this template-default.php:

template-default.php

<html>
 <head>
  <title>{TITLE}</title>
  <meta name="description" content="{DESCRIPTION}">
 </head>
 <body>
  <img src="images/title.jpg"><br>
  (something like a menu can go here)
   {CONTENT}
  <img src="images/footer.jpg"><br>
 </body>
</html>



This is an over-simplified layout but you get the point. The layout doesn't contain any part of the content, it is completely separate.

The final version of the page after it has been fully processed will look something like this. This is what will be sent to the client:

<html>
 <head>
  <title>a title</title>
  <meta name="description" content="a description">
 </head>
 <body>
  <img src="images/title.jpg"><br>
  (something like a menu can go here)

blahblahblah... content goes here.<br>

  <img src="images/footer.jpg"><br>
 </body>
</html>



(Only the colored parts are what came from the original page. The rest came from the layout. The text in red highlights the parts of the layout that were changed to reflect the page's options, and the text in green represents the text that was inserted in place of {CONTENT})

Compare this output to the original page (the top code box).

You may think of other ways to expand this template system to add more functionality and flexibility, but I've found this to be a fairly decent way to maintain a website.

That's all there is to it! I hope you have found it to be useful! If you have any questions or comments, please email me.

You may use this system on your own website, but please leave the copyright notice in template.php, and a link to my website would be greatly appreciated.
Copyright © 2003-2004 Jayson King. All rights reserved.