<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>How this site works</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
<!--
-->
</style>
</head>
<body>
<p style="color:#FFF;font-weight:bold;background:#FFC000;padding:1em 1ex;text-shadow:0 0 3px #000">This article was last updated Monday, 13 December 2004. View a newer version at my site, <a style="color:inherit" href="http://hardanswers.net/template-based-site">hardanswers.net/template-based-site</a></p>
<h1>Templates</h1>
<p>Creating static pages for a site works well when the site is small, but gets
very cumbersome as the site becomes bigger – a site-wide change has to be performed
in every single file on the site, taking a lot of time and effort. The usual
way to overcome this is by the use of templates. A template is a single page
or style that is applied to a whole site, meaning that most site-wide changes
can be done by simply editing the template, rather than every file in the site
– saving a lot of time and effort. </p>
<p>The system I’ve used allows me to store the content in plain <acronym title="Extensible Hypertext Markup Language">XHTML</acronym> files,
easily created and maintained by anyone using any standard <acronym title="Extensible Hypertext Markup Language">XHTML</acronym> editor,
such as Dreamweaver. This makes it particularly easy to deploy new content and
modify existing content. </p>
<p>The basic logic is that I have a single file that applies all the site-wide
features, such as common headers, footers and styles, and the individual page’s
content is included into this file and displayed to the user. </p>
<p>The basic concept<br />
<textarea name="textarea" cols="82" rows="5" readonly="readonly" title="">
Consistent Header
Individual Page Contents
Consistent Footer
</textarea>
</p>
<p>However, because the individual pages are stored as complete <acronym title="Extensible Hypertext Markup Language">XHTML</acronym> files,
and the resulting output page must also be a complete <acronym title="Extensible Hypertext Markup Language">XHTML</acronym> file,
it is not possible to simply include the entire individual page into the
template. The result would look something like this, which is not a valid <acronym title="Extensible Hypertext Markup Language">XHTML</acronym> page. </p>
<p>Invalid <acronym title="Extensible Hypertext Markup Language">XHTML</acronym> page<br />
<textarea name="textarea" cols="82" rows="14" readonly="readonly" title="">
<html>
<head>
<title>Page Title</title>
</head>
<body>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<p>Individual Page Body</p>
</body>
</body>
</html>
</textarea>
</p>
<p>To overcome this problem, I have a function that accepts a file name and a
tag name, and returns the contents of that tag from the given file. </p>
<p>Parse tag function<br />
<textarea name="textarea" cols="82" rows="17" readonly="readonly" title="">
// Parse file for tags
// parse the given $file for the given $tag and return any contents within
// that tag
function include_tag($tag, $file)
{
// read contents of file into $data
$data = file_get_contents($file);
// match the <$tag blah="blah">contents</$tag>
preg_match(
"/<$tag.*>(.+)<\/$tag>/sU",
$data,
$matches
);
// eval the contents from above match
eval('?>'.$matches[1]); // <?
} // end include_tag
</textarea>
</p>
<p>I can now include just the body tag from each individual page, as the content
of my template. A simple template such as this will now produce a valid <acronym title="Extensible Hypertext Markup Language">XHTML</acronym> page. </p>
<p>Simple template<br />
<textarea name="textarea" cols="82" rows="16" readonly="readonly" title="">
<?php
// Here we would have code that sets $file to the appropriate file name
$file = 'included_page.html';
?>
<html>
<head>
<title><?php include_tag('title', $file) ?></title>
</head>
<body>
<?php
include('header.inc');
include_tag('body', $file);
include('footer.inc');
?>
</body>
</html>
</textarea>
</p>
<p>Valid <acronym title="Extensible Hypertext Markup Language">XHTML</acronym> page<br />
<textarea name="textarea" cols="82" rows="10" readonly="readonly" title="">
<html>
<head>
<title>Included Page Title</title>
</head>
<body>
<p>Header things from header.inc are here</p>
<p>The content of the <body> tag of included_file.html is here</p>
<p>Footer things from footer.inc are here</p>
</body>
</html>
</textarea>
</p>
<p>With a bit more code, you have yourself a simple, functional template. </p>
<p>Simple, semi-functional template<br />
<textarea cols="82" rows="23" readonly="readonly" title="mod_rewrite code">
<html>
<head>
<?php
// set $file to the ?file part of the URI
// http://domain.com/?file=file-name
$file = $_GET[file];
// include the parse tag function
include('parse_tag_function.inc');
// print the page title
print '<title>';
include_tag('title', $file);
print '</title>';
?>
</head>
<body>
<?php
include('header.inc);
include_tag('body', $file);
include('footer.inc);
?>
</body>
</textarea>
</p>
<p>Care must always be taken to ensure that anything able to be externally passed
into a file isn’t malicious. A simple function such as this attempts to
find <acronym title="PHP Hypertext Preprocessor (server-side scripting language)">PHP</acronym> and <acronym title="Hyper Text Markup Language">HTML</acronym> files,
and returns a default <acronym title="PHP Hypertext Preprocessor (server-side scripting language)">PHP</acronym> file
if none are found. This can prevent anyone attempting to access anything unusual.</p>
<p>
<textarea cols="82" rows="7" readonly="readonly" title="file verification code">
function verify_file($file) {
switch(true) {
case file_exists($file.'.php'): return $file.'.php';
case file_exists($file.'.html'): return $file.'.html';
default: return 'default.php';
}
}</textarea>
</p>
<p>Individual files are now stored as <acronym title="Extensible Hypertext Markup Language">XHTML</acronym> or <acronym title="eXtensible Markup Language">XML</acronym>. <acronym title="Extensible Hypertext Markup Language">XHTML</acronym> files
are parsed for their body, style and title tags and these tags are then included
into the resulting output. This allows a simple template system where the content
can be created with any <acronym title="Extensible Hypertext Markup Language">XHTML</acronym> capable
editor, and I have found this to be the simplest way of creating a consistent
and easily updateable style across a site.</p>
<p>There are several advantages and a few disadvantages to this approach.</p>
<p>Disadvantages include:</p>
<ul>
<li>Slightly more processing is required to parse a file, rather than serving
straight <acronym title="Hyper Text Markup Language">HTML</acronym></li>
<li>Initial design is more complex</li>
</ul>
<p> Advantages include:</p>
<ul>
<li>Easily updateable</li>
<li>Easy to maintain</li>
<li>Consistent across an entire site</li>
<li>Content generation possible with the majority of “webpage” <acronym title="Hyper Text Markup Language">HTML</acronym> editors,
as well as by hand</li>
<li>Foreign content assumes a consistent style after parsing</li>
</ul>
<p>For further information on: </p>
<ul>
<li>eval(), see <a href="http://www.php.net/manual/en/function.eval.php" title="External Site | www.php.net">http://www.php.net/manual/en/function.eval.php</a></li>
<li>include(), see <a href="http://www.php.net/manual/en/function.include.php" title="External Site | www.php.net">http://www.php.net/manual/en/function.include.php</a></li>
<li>file_get_contents, see <a href="http://www.php.net/manual/en/function.file-get-contents.php" title="External Site | www.php.net">http://www.php.net/manual/en/function.file-get-contents.php</a></li>
<li>preg_match, see <a href="http://www.php.net/manual/en/function.preg-match.php" title="External Site | www.php.net">http://www.php.net/manual/en/function.preg-match.php</a></li>
<li>How to set $file to the file name, see Static and Persistent <acronym title="Uniform Resource Identifier">URI</acronym>’s
(<em>Coming Soon</em>) </li>
</ul>
<!-- <p>To view this template system in use, see the <a href="http://nedmartin.org/amused/_xml/source.php" title="Amused site code">code</a> from
my <a href="http://nedmartin.org/amused/" title="Amused - Because someone has to be">amused
site</a>. </p> -->
<p> </p>
</body>
</html>
Last updated Tuesday, 20 November 2012