Template-Based Site

Updated about 1 yr, 6 mths ago (March 29, 2016). Know a better answer? Let me know!

How to build a template-driven website

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.

The system we’ve used allows us to store the content in plain XHTML files, easily created and maintained by anyone using any standard XHTML editor, such as Dreamweaver. This makes it particularly easy to deploy new content and modify existing content. It’s how this site works.

The Basic Concept

The basic logic is that we 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.

Consistent Header

Individual Page Contents

Consistent Footer

However, because the individual pages are stored as complete XHTML files, and the resulting output page must also be a complete XHTML 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 XHTML page.

<html>
<head>
	<title>Page Title</title>
</head>
<body>
	<html>
	<head>
		<title>Page Title</title>
	</head>
	<body>
		<p>Individual Page Body</p>
	</body>
</body>
</html>

Parse Tag Function

To overcome this problem, we have a function that accepts a file name and a tag name, and returns the contents of that tag from the given file.

// 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>/isU",
			$data,
			$matches
		);
		// return contents from above match
		return $matches[1];

	} // end include_tag

Simple Template

We 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 XHTML page. Note that we use eval() in the content of the body, as this allows the included file to itself include PHP code.

<?php
	// Here we would have code that sets $file to the appropriate file name
	$file = 'included_page.html';
?>
<html>
<head>
	<title><?php print(include_tag('title', $file)) ?></title>
</head>
<body>
<?php
	include('header.inc');
	eval('?'.'>'.include_tag('body', $file).'<'.'?');
	include('footer.inc');
?>
</body>
</html>

The resulting valid XHTML page:

<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>

With a bit more code, you have yourself a simple, functional template. Read our answer on search-engine friendly links for some ideas on how to create functional, easy-to-use links for use with a template such as this.

<!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>
<?php
// Set $file to the ?file part of the URI
	// http://domain.com/?file=file-name
	$file = $_GET[file];

// 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>/isU",
			$data,
			$matches
		);
		// return contents from above match
		return $matches[1];

	} // end include_tag

// Print the page title
	print('<title>'.include_tag('title', $file).'</title>');
?>
</head>
<body>
<?php
	include('header.inc');
	eval('?'.'>'.include_tag('body', $file).'<'.'?');
	include('footer.inc');
?>
</body>
</html>

Caution!

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 PHP and HTML files, and returns a default PHP file if none are found. This can prevent anyone attempting to access anything unusual through this template.

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';
	}
}

Individual files are now stored as XHTML or XML. These files are parsed for their body 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 XHTML capable editor, and we have found this to be the simplest way of creating a consistent and easily updateable style across a site.

Pros & Cons

There are several advantages and a few disadvantages to this approach.

Disadvantages include:

Advantages include:

More Information

For further information on:

 

Updated about 1 yr, 6 mths ago (March 29, 2016). Know a better answer? Let me know!

Related categories [coloured].

Comment on this article (no HTML, max 1200 characters):