I think it might help to give, as Chris once called it, "a tutorial of a post"...
The structure of a program can significantly impact how much code is needed for a site, how complicated it is to add new pages, and how complicated it is to make changes. Each coder is likely to answer the question of application structure differently, but
it is the thought process involved which will determine how your app is structured. Let's see this in action!
First, we'll define our goals:
1) Our application will be a PHP 5 application where URLs are of the form "http://www.mydomain.com/file-name.php".
2) The application needs to separate CSS, JavaScript, XHTML, and page-specific content from each other.
3) Our
goal is to minimize the amount of code needed for adding pages and making changes where common routines are commonly accessible.
We can skip #1 above for the time being, but let's look at what #2 entails. First, to separate CSS, JavaScript, and XHTML, we'll want to use an XHTML structure of the form:
HTML Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" />
<script type="text/javascript" src="javascript.js"></script>
</head>
<body>
</body>
</html>
With that setup, we're now ready to take a look at adding in page-specific content while keeping it separate. Let's try a structure like this:
PHP Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php
//Allow access to a global object containing page-specific content
global $page_specific_content;
if (strlen($page_specific_content->title) == 0) {
//Page title was not set, so default to website URL
$page_specific_content->title = $_SERVER['HTTP_HOST'];
}
//Output page title
echo ' <title>'.$page_specific_content->title."</title>\n";
//Output page stylesheet include(s)
if (strlen($page_specific_content->stylesheet) > 0) {
if (is_array($page_specific_content->stylesheet)) {
//An array of stylesheet file paths.
echo " <link rel=\"stylesheet\" type=\"text/css\" href=\"".implode("\" />\n <link rel=\"stylesheet\" type=\"text/css\" href=\"",$page_specific_content->stylesheet)."\" />\n";
} else if (is_string($page_specific_content->stylesheet)) {
//A single stylesheet
echo ' <link rel="stylesheet" type="text/css" href="'.$page_specific_content->stylesheet."\" />\n";
}
}
//Output page javascript include(s)
if (strlen($page_specific_content->javascript) > 0) {
if (is_array($page_specific_content->javascript)) {
//An array of javascript file paths.
echo " <script type=\"text/javascript\" src=\"".implode("\"></script>\n <script type=\"text/javascript\" src=\"",$page_specific_content->stylesheet)."\"></script>\n";
} else if (is_string($page_specific_content->javascript)) {
//A single javascript
echo ' <script type="text/javascript" src="'.$page_specific_content->javascript."\"></script>\n";
}
}
//Output other headers
if (strlen($page_specific_content->xhtml_header) > 0) {
if (is_array($page_specific_content->xhtml_header)) {
//An array of xhtml_header file paths.
echo implode("\n ",$page_specific_content->xhtml_header);
} else if (is_string($page_specific_content->xhtml_header)) {
//A single xhtml_header
echo ' '.$page_specific_content->xhtml_header."\n";
}
}
?>
</head>
<body>
<?php
if (strlen($page_specific_content->xhtml_body) == 0) {
echo $page_specific_content->page_not_found;
} else {
echo $page_specific_content->xhtml_body;
}
?>
</body>
</html>
Now, to demonstrate a couple of methods for applying point #3 above, we could simplify the code above to either of these 2 methods (and
many others):
PHP Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php
//Allow access to a global object containing page-specific content
global $page_specific_content;
if (strlen($page_specific_content->title) == 0) {
//Page title was not set, so default to website URL
$page_specific_content->title = $_SERVER['HTTP_HOST'];
}
//Output page title
echo ' <title>'.$page_specific_content->title."</title>\n";
$custom_includes = array('stylesheet'=>array('prefix'=>' <link rel="stylesheet" type="text/css" href="', 'suffix'=>"\" />\n"),
'javascript'=>array('prefix'=>' <script type="text/javascript" src="', 'suffix'=>"\"></script>\n")
);
//Output page custom_includes
foreach ($custom_includes as $custom_type=>$fixes) {
if (strlen($page_specific_content->$custom_type) > 0) {
if (is_array($page_specific_content->$custom_type)) {
//Custom type is an array
echo $fixes['prefix'].implode($fixes['suffix'].$fixes['prefix'], $page_specific_content->$custom_type).$fixes['suffix'];
} else if (is_string($page_specific_content->$custom_type)) {
//Custom type is a string
echo $fixes['prefix'].$page_specific_content->$custom_type.$fixes['suffix'];
}
}
}
//Output other headers
if (strlen($page_specific_content->xhtml_header) > 0) {
if (is_array($page_specific_content->xhtml_header)) {
//An array of xhtml_header file paths.
echo implode("\n ",$page_specific_content->xhtml_header);
} else if (is_string($page_specific_content->xhtml_header)) {
//A single xhtml_header
echo ' '.$page_specific_content->xhtml_header."\n";
}
}
?>
</head>
<body>
<?php
if (strlen($page_specific_content->xhtml_body) == 0) {
echo $page_specific_content->page_not_found;
} else {
echo $page_specific_content->xhtml_body;
}
?>
</body>
</html>
or
PHP Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php
//Allow access to a global object containing page-specific content
global $page_specific_content;
if (strlen($page_specific_content->title) > 0) {
//Page title was not set, so default to website URL
$page_specific_content->title = $_SERVER['HTTP_HOST'];
}
//Output page title
echo ' <title>'.$page_specific_content->title."</title>\n";
//Output headers
if (strlen($page_specific_content->xhtml_header) > 0) {
if (is_array($page_specific_content->xhtml_header)) {
//An array of xhtml_header file paths.
echo implode("\n ",$page_specific_content->xhtml_header);
} else if (is_string($page_specific_content->xhtml_header)) {
//A single xhtml_header
echo ' '.$page_specific_content->xhtml_header."\n";
}
}
?>
</head>
<body>
<?php
if (strlen($page_specific_content->xhtml_body) == 0) {
echo $page_specific_content->page_not_found;
} else {
echo $page_specific_content->xhtml_body;
}
?>
</body>
</html>
For the rest of this article I'm going to be working with the first of these 3 code segments.
Next we need to establish a structure for our application which allows us to use this XHTML template. First, we'll need to create a class for our $page_specific_content variable to use. Let's use this:
PHP Code:
class XHTMLPage {
private $settings = array();
public function __construct() {
//Initialize variable(s)
$this->settings['xhtml_body'] = '';
}
public function __get($variable_name) {
switch ($variable_name) {
case 'title':
case 'stylesheet':
case 'javascript':
case 'xhtml_header':
case 'xhtml_body':
if (empty($this->settings[$variable_name])) {
return '';
} else {
return $this->settings[$variable_name];
}
break;
case 'page_not_found':
if (empty($this->settings[$variable_name])) {
return 'Page Not Found';
} else {
return $this->settings[$variable_name];
}
break;
}
}
public function __set($variable_name, $variable_value) {
switch ($variable_name) {
case 'title':
case 'page_not_found':
$this->settings[$variable_name] = $variable_value;
break;
case 'xhtml_body':
$this->settings[$variable_name] .= $variable_value;
break;
case 'stylesheet':
case 'javascript':
if (empty($this->settings[$variable_name])) {
//First entry, so treat as a string
$this->settings[$variable_name] = $variable_value;
} else {
//Not the first entry, so treat as an array
if (!is_array($this->settings[$variable_name])) {
$this->settings[$variable_name][] = $this->settings[$variable_name];
}
$this->settings[$variable_name][] = $variable_value;
}
break;
case 'xhtml_header':
$this->settings[$variable_name][] = $variable_value;
break;
}
}
}
We have now structured our application and can begin creating pages! Let's create an index page:
PHP Code:
<?php
global $page_specific_content;
require_once('XHTMLPage.php');
$page_specific_content = new XHTMLPage();
$page_specific_content->title = 'Welcome';
$page_specific_content->stylesheet = 'stylesheet.css';
$page_specific_content->javascript = 'javascript.js';
//$page_specific_content->xhtml_header = '';
$page_specific_content->xhtml_body = '<h1>WELCOME</h1>';
$page_specific_content->xhtml_body = '<p>I\'m excited to have this page up for you!</p>';
require_once('xhtml_template.php');
?>
To create additional pages, we need only duplicate index.php and change the variables. To update the template (to include navigation, for example), we only need to edit the template. We have, in effect, achieved our goals!
I have attached files demonstrating this layout to this post for your reference and use... they're free to all.
Now, when I personally create an application structure, there are generally far more goals for the application and the structure becomes much more sophisticated, but I use the same methodology above in designing the code. The key thing to the success of an application structure is to begin by defining your goals. Much of the rest of the application becomes necessary as a means of fulfilling your goals.