Our first PHP task is an easy one, but one of the most important uses of PHP.
Most Web pages have regions, like this:

Figure 1. Web page regions
Different parts of a page are put into the regions:

Figure 2. Using the regions
All of the pages on a site usually have the same structure. Some regions have the same content. For example, every page might have the same thing in the bottom region. CoreDogs is like this. No matter what page you look at, the bottom is the same.
Well, almost. The message on the right of the footer is chosen randomly for each page.
Suppose you have a Web site with, say, 200 pages. Every page has this in the bottom region:

Figure 3. Original footer
Your client (or employer, school, sister, whoever) wants to change it to this, on every page:

Figure 4. New footer
If each page is a separate HTML, that means you have to change 200 files. Ack! What a pain.
But if you use PHP to set up a template for the site, you can change all 200 pages by just changing one file. You read that right – change the entire site by editing one file!
Talk about a productivity win.
If you use just one thing from this book, make it this one: creating active Web templates with PHP. That’s what you’ll learn in this chapter. And it’s one of the easiest things you can do with PHP.
By the end of this chapter, you should:
One thing to keep in mind: this can get confusing! Not so much because the PHP for Web templates is complex. It’s not. It’s simple, in fact.
The problem is that there are so many pieces to a Web site. HTML file, CSS files, JavaScript files, link tags, image tags, and other things. They all need special treatment.
For this chapter to make sense, you’ll need to know how Web sites are put together. I’ll assume that you’ve worked through the ClientCore book, and more-or-less understand it. You should know about images, links, nav bars, CSS files, JavaScript files, a little jQuery, and page layouts.
Let’s get started!
By the end of this lesson, you should:
print statement.Let’s take a look at a simple PHP program. It will show the time on the server. This is quite likely to be in a different time zone from the one you’re in, but that’s OK.
To begin, click here. A new window (or tab) opens, and a page shows with the time on the server.
Now look at the page’s URL. It will look something like this:
http://coredogs.com/content_media/lessons/servercore/web-site-templates/server-time.php
Look at the extension of the file. Usually, we see .html. This one is .php. What’s the difference?
When a Web server gets a request for a URL, it looks at the extension to figure out what to do. Here is the process for an HTML file.

Figure 1. Get an HTML file
The browser sends a request for x.html to the server (1). The server looks on its hard disk, and reads the file (2). It sends the data it read back to the browser (3).
You can read about the details on the page Static Web pages.
But when the URL ends in .php, the server does something else.

Figure 2. Get a PHP file
The browser sends a request to the server, this time for x.php. The server reads the file from its disk drive (2). The server notices the file has the extension .php, so it sends the data it read to the PHP interpreter (3).
The PHP interpreter is a program that runs on the server, just like any other program. It can follow instructions written in the PHP programming language.
The PHP interpreter follows the instructions in the data it got from the server (4). Most of the time, PHP code is embedded inside HTML code.
The PHP interpreter sends its results back to the server (5). The server sends the data back to the browser (6).
All of this happened when you clicked on a link to http://coredogs.com/content_media/lessons/servercore/web-site-templates/server-time.php. The browser asked the Web server at coredogs.com for the the data at server-time.php (1 in Figure 2). The server read the file server-time.php from its disk drive (2), and passed the file’s contents to the PHP interpreter (3). The interpreter ran the code (4), and gave the results back to the Web server (5). The server then sent the data back to your browser (6).
That’s a lot of stuff happening, just because you clicked a link!
Have a look at the HTML code that the browser got from this page. (In Firefox, hit Control-U. In other browsers, right-click and select View source or Show source, or whatever it says.)
You’ll see something like this:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Server time</title>
</head>
<body>
<p>The time at the server is
04:10:22 PM </p>
</body>
</html>
Figure 3. The HTML
It looks just like regular HTML, although the formatting around line 8 is a little strange. There is no PHP or anything here, just plain HTML.
The PHP in the file server-time.php generates normal HTML. The browser can’t tell the difference between a page manually typed in by a person, and one that’s generated. That’s the beauty of PHP; the browser just gets HTML, a language it already understands.
Now click the server time link again. You’ll get a different time, assuming that a few seconds have elapsed. Have a look at the HTML source of the new page. It’s almost the same as it was. Just the time is a little different.
In fact, each time your browser asks for server-time.php, it will get plain HTML, but it will get different HTML (if the requests are at least a second apart). The URL is always the same:
http://coredogs.com/content_media/lessons/servercore/web-site-templates/server-time.php
But the PHP in the file server-time.php creates different HTML each time.
server-time.phpHere’s what’s in the file server-time.php on the server’s hard disk:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Server time</title>
</head>
<body>
<p>The time at the server is
<?php
print date('h:i:s A');
?>
</p>
</body>
</html>
Figure 4. server-time.php
Lines 1 to 8 and 12 to 14 are regular HTML. The PHP interpreter just passes them back to the server unchanged. The magic happens in lines 9 to 11.
Let’s make sure we understand what I wanted the page to show. I wanted the server to send back HTML that looked like this:
<p>The time at the server is (time goes here)</p>
When you program in PHP, you are programming indirectly. You write PHP code that creates HTML, or text that gets
embedded in HTML. The HTML then gets returned to the browser for rendering. So remember:
You write PHP that writes HTML.
Line 9 is the PHP opening tag: <?php. It tells the PHP interpreter that some PHP is about to appear. The interpreter runs the code until it hits the close tag in line 11: ?>.
Line 10 is:
print date('h:i:s A');
print is a PHP statement that says “Output what follows.” date() is a PHP function that gets the current date and time, and returns it. The stuff in the parentheses (()) is a format, telling date how to show the date and time. In this case, the hours, then a colon (:), then the minutes, then another colon, then the seconds, then a space, and then an AM/PM indicator.
The statement ends with a semicolon (;). All statements in PHP end this way. If you leave off the semicolon, the PHP interpreter will get confused, and complain.
The result? The print statement outputs the current time.
Upload the server time program on to your own server. One way is to:
coredogs/servercore/web-templates/server-time, and save the file there. coredogs is this site, servercore is the book on CoreDogs, web-templates is the chapter in the book, and server-time is the exercise in the chapter. It seems like a lot of typing, but it’s very important to keep your files organized.Name the file whatever you want. If you name it index.php, it will be the default file in that directory. You can read more about default files.
If you installed XAMPP on your computer, and you put the file somewhere under your htdocs directory, you can access it through your browser. For example, suppose you saved the file as:
C:\xampp\htdocs\coredogs\servercore\web-templates\server-time\server-time.php
This is a file path for a Windows machine. If you use a Mac or Linux box, your path will have a slightly different format.
Remember that C:\xampp\htdocs\ is the root of the Web server on your computer.
Make sure your Apache server is running (use the XAMPP control panel to start it). In your browser, type the URL:
http://localhost/coredogs/servercore/web-templates/server-time/server-time.php
http://localhost/ maps to C:\xampp\htdocs\. The rest of the path maps to your PHP file.
Once the program works, upload the file to your hosting account, and point your browser there. (If you didn’t install XAMPP on your computer, you will need to upload the file before you can test it.) I recommend that you use the same file structure on your hosting account that you used on your own computer.
Now, change the page. Add an <h1> that says something like:
Renata’s first PHP program
Of course, replace Renata with your own name.
Upload the new version. Enter the URL of your first PHP program below.
(Log in to enter your solution to this exercise.)
Write a PHP page that will show the IP addresses of your browser, and the server the page is running on.
You can get the IP addresses with:
$_SERVER['REMOTE_ADDR']
$_SERVER['SERVER_ADDR']
Hint: base this on the server time example.
You can run my solution.
Upload your solution to your server. Put the result below.
(Log in to enter your solution to this exercise.)
.php extension, it sends the file to the PHP interpreter.Outputting stuff will help you create dynamic Web templates. The next thing you need to know is how to insert one file inside another.
Onward! To glory!
You saw how the print statement puts data into the HTML. Let’s see how you can put entire files into the HTML.
By the end of this lesson, you should:
PHP has several statements that insert files: include, require, and require_once. We’ll just talk about one of them: require.
Suppose we create a file that contains HTML to show a footer for every page on a Web site. Here it is:
<div id="footer"> Copyright © 2010 | All rights reserved </div>
Figure 1. Footer code.
This is a complete HTML page, just a fragment of HTML. It wouldn’t work by itself. Let’s call the file footer.inc. The .inc reminds us that the file is meant to be included in another file.
Here’s the PHP page include-footer.php:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Including a footer</title>
</head>
<body>
<h1>Hi there!</h1>
<p>I am a page. Aren't I wonderful?</p>
<?php
require 'footer.inc';
?>
</body>
</html>
Figure 2. Including a footer
The require statement reads the file it’s given, and inserts it. Any PHP in the included file is executed. If the PHP interpreter can’t find the file, it shows an error message.
You can try it. Make sure you have a look at the HTML source. As far as the browser knows, the content of footer.inc was typed directly into include-footer.php.
The code in Figure 2 is in a file called include-footer.php. It has the line:
require 'footer.inc';
There is no directory given, just a file name. Oo where will the PHP interpreter look for footer.inc?
The answer: in the same directory as include-footer.php. So if include-footer.php is in /my/directory/of/doom/, then the PHP interpreter will look for /my/directory/of/doom/footer.inc.
When you’re using dynamic Web templates for real, this won’t work very well. Suppose you were creating a site with this structure:

Figure 3. Site structure.
The file at /index.php is the home page of the site. The file at /articles/index.php shows a list of articles. There are other things like blog entries, products, and so on, but we don’t need to consider them here.
Suppose you put this line into both /index.php and /articles/index.php:
require 'footer.inc';
You would need one footer.inc for /index.php and another for /articles/index.php:

Figure 4. Duplicate footer files.
But what’s the point of that? If we wanted to change the footer text across the entire site, we’d have to change all of the footer.inc files.
What we really want is for both /index.php and /articles/index.php to refer to the same footer.inc.

Figure 5. Just one footer file.
footer.inc is in a directory called library. PHP developers often move shared files to a directory like this, and call it library, lib, includes, common, or something like that.
But we have to change the require statements to make this work. Here is the require statement from /index.php:
require 'library/footer.inc';
Here is the one for /articles/index.php:
require '../library/footer.inc';
The .. means “go up a level.”
To brush up on how to use paths to navigate between directories, see the discussion of absolute, relative, and root relative links.
Let’s see how this would work in an entire Web site.
Let’s create a simple site called The Dog Site. It has a home page and two sections: dog profiles, and articles.

Figure 6. Site overview.
Each of the two sections of the site – dog profiles and articles – has a main page. Each one is linked from the home page.
Here is the home page:

Figure 7. Home page.
Here is the main page for the dog profile section:

Figure 8. Dog profile main page.
Here is the main page for the articles section:

Figure 9. Articles main page.
You can try the site.
Let’s create the directory tree for the site, that is, the directories on the server that all the files will go into. We’ll make a directory for each section of the site: dog profiles and articles.
The header is the same on every page, so let’s pull that out and put it in its own file. Here’s the code:
<!-- Header file, to be included into every page. --> <h1>The Dog Site</h1> <h2>Bringing you happiness since last week</h2> <hr>
Figure 10. HTML for the header.
Let’s put the code into the file header.inc, and put the file into a library directory.
Here is the directory tree so far.

Figure 11. Initial tree.
The home page is index.php. Recall that if a browser sends a URL to a Web server, and the URL does not have a file name, then the browser uses a default name. In ClientCore, we used index.html as the default. index.php can be the default as well.
So if a browser asks for:
http://dogthing.com/play/
the server will run:
http://dogthing.com/play/index.php
Let’s see what the tree looks like when all the files are added:

Figure 12. Complete tree.
All of the PHP files are going to have a require statement, to insert header.inc. But since the PHP files are in different directories, they will use different paths to navigate to header.inc. Here are the paths for some of the files.
| File | Path in require |
|---|---|
| /index.php | library/header.inc |
| /articles/index.php | ../library/header.inc |
Figure 13. Paths in some of the files.
Complete figure 13. Give the path in the require statement for every PHP file.
You can check your solution by downloading a zip file of the site. Expand the zip file to see the PHP code.
(Log in to enter your solution to this exercise.)
Download and expand this zip file. It will create a directory tree like this:

Figure 1. Directory tree
Open up wombat.php. Add require statements to create a page that looks like this:

Figure 2. Output
Use only relative file paths.
Upload the entire tree to your server. Put the URL below.
You can see my solution, but try it yourself first.
(Log in to enter your solution to this exercise.)
In this lesson, you learned:
require statement.But there’s a problem. It’s easy to break links to images and other resources. Let’s fix that in the next lesson.
You’ve seen how to use the require statement to insert one file into another. But do it the wrong way, and your site won’t work. Let’s look at the problem and a solution.
By the end of this lesson, you should:
Let’s look again at the dog site. Remember that it has two sections: articles and dog profiles. Here’s the directory tree:

Figure 1. Directory tree
The file header.inc is inserted in all of the other PHP files. For example, here’s how it is inserted into playing-with-dogs.php:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Playing with dogs | The Dog Site</title>
</head>
<body>
<?php
require '../library/header.inc';
?>
<h2>Article: Playing with dogs.</h2>
<p>Pretend there is some content here.</p>
<p><a href="index.php">Back to the article list</a></p>
</body>
</html>
Figure 2. Code for playing-with-dogs.php
Line 9 inserts a header file that is the same across the entire site. The path says “go up to the parent directory, then down into the library directory, then insert the file header.inc.”
Here’s the header:
<!-- Header file, to be included into every page. --> <h1>The Dog Site</h1> <h2>Bringing you happiness since last week</h2> <hr>
Figure 3. HTML for header.inc
You can try the site. You can also download a zip file with all of the PHP and other files.
The client wants to add the following logo to the header of every page:

Figure 4. Logo
“No problem,” we say. We put the image file (logo.png) in the library directory.

Figure 5. Logo in the library directory
We change header.inc to:
<!-- Header file, to be included into every page. --> <h1><img src="logo.png" alt="Logo">The Dog Site</h1> <h2>Bringing you happiness since last week</h2> <hr>
Figure 6. First try at the new header.inc
But this doesn’t work. Look at the home page. You’ll see something like:

Figure 7. Broken logo
Exactly what you see depends on how your browser handles broken image links.
So what’s the problem? Tell your browser to show you the HTML of the page (Control+U, or right click), and you’ll see:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Welcome | The Dog Site</title>
</head>
<body>
<!-- Header file, to be included into every page. -->
<h1>The Dog Site</h1>
<h2><img alt="Logo" src="logo.png">Bringing you happiness since last week</h2>
<hr> <p>Welcome to the dog site.</p>
<p>See some <a href="dog-profiles/index.php">dogs</a>.</p>
<p>Read an <a href="articles/index.php">article</a>.</p>
</body>
</html>
Figure 8. HTML of index.php with broken logo
Again, the layout is a little strange around line 9, because the HTML here is inserted by PHP.
Line 10 contains the logo HTML. It’s exactly what we put into header.inc. So what’s the problem?
It has to do with the directory that logo.png is in. The file is in the library directory (See Figure 5). But the browser gets this code:
<img alt="Logo" src="logo.png">
There is no path, just logo.png. So the browser tries to load the image from the same directory that index.php is in.
index.php is in the root directory of the site (/). So the browser tries to load /logo.png.
Oops.
Every page on the site has the same problem. For example, /articles/why-dogs-are-great.php also has the line:
<img alt="Logo" src="logo.png">
inserted by the PHP require statement. The browser tries to load logo.php from the same directory as why-dogs-are-great.php. So it tries to load /articles/logo.png.
Argh!
How to fix it?
One choice is to copy logo.png to every directory, but that’s a really bad idea. If we wanted to change the logo for the site, we’d have to find and change every copy of logo.png.
A better choice (but not the best) is to change the inserted code to:
<!-- Header file, to be included into every page. --> <h1><img src="/library/logo.png" alt="Logo">The Dog Site</h1> <h2>Bringing you happiness since last week</h2> <hr>
Figure 9. Root relative path in header.inc
The src attribute on line 2 has changed. It has the full path to the logo. This is a root relative URL. It says “Go to the root of the Web site, then go down into the library directory, then find logo.png.”
This works! But…
Root relative URLs cause their own problems. They reduce the portability of a site, that is, your ability to move all of the files in the site around.
Remember that part of CoreDogs is not just learning the tech, but learning to think like a Weber. That is, to understand how people who create Web sites do their work.
On just about every project, you want to have separate a test version of the site. You tell your client “go look at the test version to see what I’m doing.” Then you can talk about changes.
Let’s say you put a test version of the site on http://mytestsite.com/dogsite/. You also have test versions of other sites, like http://mytestsite.com/catsite/ and http://mytestsite.com/hipposite/. This is common Weber practice; keep test versions on different domains from the product site.
But there’s a problem. You’ve moved the files into a directory called dogsite. The root relative path of the logo file is now /dogsite/library/logo.png. Your library file (header.inc) has /library/logo.png. So you have to change it to /dogsite/library/logo.png. Argh!!
But every time you copy the test version of the site to the production version, you have to remember to change back every root relative path. Double argh!!
And you have to do this for every root relative path! Not just the logo, but CSS files, JavaScript files, ...
Triple argh!!!
There are ways around this, too, but the fact is that root relative URLs are a pain.
But there’s a good solution. One that works well for template-based, dynamic Web sites.
What we’re going to do is change the HTML code that header.inc inserts. Instead of just src="logo.png", it will insert src="library/logo.png", or src="../library/logo.png", or src="../../../library/logo.png", or whatever each page needs.
We’ll do this by creating a variable on each page, and having header.inc use that variable.
If you remember back to JavaScript, you learned that a variable is a piece of computer memory that’s given a name. For example, here’s some JavaScript that takes whatever the user typed into a form field, puts it into the variable user_name, and tests whether the variable is empty.
user_name = $("#user").val();
if ( user_name == "" ) {
alert("Sorry, you must enter a user name.");
}
Figure 10. JavaScript variable
PHP has variables, too. They act much like JavaScript variables. One difference is that their names all begin with $ (a dollar sign).
Our solution to the logo problem is in two steps:
header.inc.Let’s have a look. Here’s the directory tree again.

Figure 5 (again). Logo in the library directory
See the file playing-with-dogs.php in the articles directory? Here is the new version:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Playing with dogs | The Dog Site</title>
</head>
<body>
<?php
$path_to_root = '..';
require $path_to_root . '/library/header.inc';
?>
<h2>Article: Playing with dogs.</h2>
<p>Pretend there is some content here.</p>
<p><a href="index.php">Back to the article list</a></p>
</body>
</html>
Figure 11. Code for playing-with-dogs.php
Line 9 creates a variable called $path_to_root. Remember that variables begin with $ in PHP. The string “..” is put into the variable. You can put any characters you like into a variable. You can put numbers, too, and other things.
Notice that the statement ends with a semicolon (;). All statements must have a semicolon at the end. JavaScript is forgiving about this. PHP is not.
Line 10 is:
require $path_to_root . '/library/header.inc';
The period (.) is PHP’s string concatenation operator. It sticks two strings together. So 'Big' . 'ger' would yield 'Bigger'.
JavaScript uses plus (+) to mean the same thing, but if you remember, that causes problems, because + in JavaScript also means “add two numbers together.” PHP doesn’t have that problem. PHP has two operators (. and +) that mean two different things.
Let’s look again:
$path_to_root = '..'; require $path_to_root . '/library/header.inc';
Part of Figure 10 (again). Code for playing-with-dogs.php
.. is the path from playing-with-dogs.php to the Web root. /library/header.inc is the path from the Web root to the header file. Put them together, and you get ../library/header.inc, which is the path from playing-with-dogs.php to the header file.
So far, so w00f. As long as $path_to_root is set correctly for every page, the header file will be found correctly.
Note that this variable is declared in files that other files (like the header) are inserted into. These are the files with require statements, not the files that are inserted by the require statements.
What about the files that are inserted? They use the variable that was declared. Let’s look at the new header.inc.
<!-- Header file, to be included into every page. --> <h1><img src="<?php print $path_to_root; ?>/library/logo.png" alt="Logo">The Dog Site</h1> <h2>Bringing you happiness since last week</h2> <hr>
Figure 12. Code for header.inc
Remember that the print statement outputs stuff into the HTML stream. It can output anything, anywhere. Including file paths!
If $path_to_root has ‘..’ in it, then line 2 will produce:
<h1><img src="../library/logo.png"…
As before, $path_to_root has the path from the file that the code in Figure 12 is inserted into, to the Web root. /library/logo.png is the path from the Web root to the logo file. Put them together, and you have the path from the page the header code is inserted into, to the logo.
You can try this version of the site. Look at the HTML for a few pages, and check out the paths to the logo. By the way, you know that “..” means “go up one level to the parent.” “.” means “stay where you are.” You’ll see that on the home page.
You can download a zip file of the site if you want.
This approach works for all paths, whether they’re for images, links, CSS files, JavaScript files, or anything else. To see that, suppose we wanted to add a contact page to the site, with a link from the header of every page:

Figure 13. Link to contact page in header
The contact page is at /contact.php, that is, in the Web root, along with the site’s home page.

Figure 14. Contact page in directory tree
We can add a contact link to every page on the site by only changing header.inc! W00f!
Here is what the new header.inc would look like.
<!-- Header file, to be included into every page. --> <h1><img src="<?php print $path_to_root; ?>/library/logo.png" alt="Logo">The Dog Site</h1> <h2>Bringing you happiness since last week</h2> <p><a href="<?php print $path_to_root; ?>/contact.php">Contact us</a></p> <hr>
Figure 15. New code for header.inc
Line 4 does the trick. $path_to_root contains the path from the page the code is inserted into to the Web root. The contact page is right there in the Web root; that’s just /contact.php.
You see how we could add the contact link by changing only one file? It wouldn’t matter how many pages were in the site. 10? 100? 10,000? Change just one file, and everything gets changed.
This is a Big Win for someone who works on Web sites, especially someone who does it professionally. Webers don’t think just about the end result, that is, the site that users will see. They also think about the work processes that create that site.
Webers think about productivity. The more productive they are, the better value they give employers and clients.
Modify your solution to the first Wombat exercise. Add a variable to wombat.php that has the path to the Web root. Use the variable in all the require statements.
Upload the file to your server. Put the URL below.
You can see my solution, but try it yourself first.
(Log in to enter your solution to this exercise.)
Using a variable like $path_to_root works with all kinds of paths in the HTML. We’ve fixed paths to images (the logo) and links (the contact page) in this lesson.
But there are often paths in JavaScript code. To images, for example. We need to fix them as well. How?
In the previous lesson, we saw how to use a PHP variable to keep links and images working in a dynamic templating system. We got the Big Win of being able to reuse things like page headers on all pages of a site.
Let’s look at reusing JavaScript files. The goal is the same. Have one JavaScript file that’s included across all pages. If we want to change the JavaScript, change that one file, and every page is changed.
By the end of this lesson, you should:
Here’s a page with an image and a link.

Figure 1. Sample page
Try it, but ignore the Another link for the moment. (We’ll get back to it.)
Move the mouse over the image, and it changes. Move the mouse out, and it changes back. There are two different images. They are swapped in and out when the mouse moves over an <img> tag (more on that later).
Here’s the directory tree for the site.

Figure 2. Tree
There are two pages. One is /index.html, the one we’ve been looking at. There’s another page, /another/index.html. We’ll get to that later.
The images are in the library directory. The JavaScript that handles the image changing is in the file js-example.js. It’s in the library directory as well.
Why are the files in a separate library directory? Because they’re going to be reused across the site.
Here’s the HTML. No PHP yet.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="library/js-example.js"></script>
<title>JavaScript Example - Broken</title>
</head>
<body>
<h1>JavaScript Example - Broken</h1>
<h2>Home</h2>
<p><img id="message" src="library/welcome.png" alt="Welcome"></p>
<p><a href="another/index.html">Another</a></p>
</body>
</html>
Figure 3. HTML
Look at line 12. There’s the <img> tag that shows the current image. It has an id of message.
The JavaScript that changes the image is in the file /library/js-example.js, referenced in line 6.
(Line 5 is a reference to the jQuery library on a Google server. It uses an absolute URL, and is not affected by the templating system.)
Here’s the contents of /library/js-example.js. This is the JavaScript code that does the image switching.
$(document).ready(function() {
$('#message').hover(
function(){
$('#message').attr('src', 'library/go_away.png');
},
function(){
$('#message').attr('src', 'library/welcome.png');
}
);
});
Figure 4. JavaScript
When the mouse goes over the image, the <img> tag shows go_away.png (line 4). When the mouse leaves the image, it’s set back to welcome.png (line 7).
So far, so good. Now try the page again. But this time, follow the Another link. This loads the page /another/index.php. As you can see in Figure 2, it’s in a subdirectory.
The image shows up. But when you move the mouse over the image, go_away.png doesn’t appear. What’s the deal?
It’s the same problem we had on the previous lesson. It’s the file paths. Remember, you’re looking at the file:
/another/index.html
This JavaScript executes:
...
attr('src', 'library/go_away.png')
library/go_away.png is a relative path, so the browser looks for the file relative to the current page. It tries to load:
/another/library/go_away.png
But the file is not here.
Argh! Yet again!
You can download all the files from this example.
Let’s look at a fix that uses just JavaScript, not PHP. It uses a similar approach, though: Set a variable with the path to the root.
Let’s add a few lines to /index.html. This is the first page we saw, the one that worked. Here is the new head section of the page.
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="library/js-example.js"></script>
<script type="text/javascript">
var path_to_root = ".";
</script>
<title>JavaScript Example - Fixed with JavaScript</title>
</head>
Figure 5. JavaScript fix
Lines 7 to 9 are new. Line 8 creates a JavaScript variable called path_to_root. It’s set with – guess what? – the path from /index.html (the file the code is in) to the root of the Web site. /index.html is in the root directory. “.” means “stay right here.”
We change /another/index.php as well, the page that didn’t work. Here’s what it changes to:
<script type="text/javascript"> var path_to_root = ".."; </script>
Figure 6. JavaScript fix for another file
The “..” says, “To get to the root, go up to the parent.”
Let’s say we had the file hippo/llama/lion/dog.html. It’s code would be:
<script type="text/javascript"> var path_to_root = "../../../"; </script>
Figure 7. A long path
dog.html is in the subdirectory lion. Line 8 says, “To get to the root, go up a level, go up a level, and go up a level.”
So, on each page, we create a JavaScript variable with the path from that page to the root of the Web page.
Now, what do we do with that variable? Let’s change /library/js-example.js. Remember that’s the file with the JavaScript code that handles the image switching. Here’s the new code:
$(document).ready(function() {
$('#message').hover(
function(){
$('#message').attr('src', path_to_root + '/library/go_away.png');
},
function(){
$('#message').attr('src', path_to_root + '/library/welcome.png');
}
);
});
Figure 8. New JavaScript
path_to_root has the path from the page to the root. /library/go_away.png is the path from the root to the new image file. So:
path_to_root + '/library/go_away.png'
is the path from the page to the new image file.
You can try it. You can also download all the files. Note that everything works just fine.
W00f!
We have a JavaScript line like this, to get the JavaScript code in the library files to work right:
var path_to_root = "..";
We did the same thing in the last lesson, to get the file paths in the library HTML files (like the header and footer) to work right. But we used PHP:
$path_to_root = '..';
We could combine them, and get rid of the duplication. We’d end up with something like this for the head section of a page:
<head>
<?php $path_to_root = '..'; ?>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="../library/js-example.js"></script>
<script type="text/javascript">
var path_to_root = "<?php print $path_to_root; ?>";
</script>
<title>JavaScript Example - Fixed with JavaScript</title>
</head>
Figure 9. PHP and JavaScript
Line 4 sets a PHP variable with the root path. Line 9 puts that into a JavaScript variable. With this approach, we only need to remember to set the PHP variable. The JavaScript variable will be set correctly.
/library/js-example.js doesn’t change. The variable it needs – path_to_root – is still set correctly.
For this to work, you need to rename the HTML files, giving them a .php extension. Remember that PHP statements are only executed in files that have the extension .php. Here is the new directory tree:

Figure 10. New tree
You can try this approach. You can also download the files.
Notice what you are doing here. Look at this again.
<script type="text/javascript"> var path_to_root = "<?php print $path_to_root; ?>"; </script>
Part of Figure 9 (again). PHP and JavaScript
This puts something like this in the code sent to the browser:
<script type="text/javascript">
var path_to_root = "..";
</script>
That we are doing is using PHP code to write JavaScript code!
This is so weird. But it’s done all the time. Browsers know how to run JavaScript, just as they know how to display HTML. We take advantage of this. We write PHP that writes JavaScript, just as we write PHP that writes HTML. The browser then does its thing with what we send it.
This is a good example of how computers work in layers. The PHP layer creates stuff for the HTML/JavaScript layer.

Figure 11. Layers
Each layer has languages it understands. The layer underneath it creates stuff in those languages.
Try this site with a broken logo animation. Move the mouse over the logo image. It works on the first page, but not the others.
Download a zip file of the site. Fix it, using PHP and JavaScript variables.
You can check my solution and download a zip file of it.
But try it yourself first!
Upload your solution to your server. Put the URL below.
(Log in to enter your solution to this exercise.)
Let’s see where we are.
require statement.Let’s put this all together, and create a complete dynamic templating system for a Web site.
You know how to use require statements. You know how to use variables to fix broken paths.
Now let’s put it all together. Let’s make a site that has a complete PHP templating system.
By the end of this lesson, you should:
Let’s remake the dog site we looked at a couple of lessons ago. Here is its overall structure:

Figure 1. Site structure
There are two sections in the site: dog profiles and articles. The profiles section has profiles of several dogs. The articles section has articles on dog issues.
Here is the home page of the new site.

Figure 2. Home page
Note that the buttons on the nav bar match the site structure in Figure 1.
The dogs link on the home page, and the dogs button in the nav bar, link to the main page of the dogs section of the site. Here it is:

Figure 3. Main page of the dogs section
Each link shows a page about a dog. Here’s a sample:

Figure 4. Dog profile
Each dog profile has a photo of the dog.
The other section of the site in Figure 1 is the articles section. Here is its main page:

Figure 5. Main page of the articles section
The page has links to each article. Here’s one of them.

Figure 6. An article
There is one other page: the contact form. A link to it is in the footer of every page. Here it is:

Figure 7. Contact page
You can try the site yourself. You can also download the site.
Each page has the same layout:

Figure 8. Page layout
There are four regions on the page: top, left, center, and bottom. There is no right region in this layout.
The top region has a header. It contains two images (the logo and header image), and some text (a site subtitle). The content of the header – the images and text – is the same on every page.
The left region has a nav bar that is the same on every page. It has three images. The images switch when the mouse hovers over them:

Figure 9. Mouse hover effect
The bottom region has a footer that is the same on every page. It contains some text, and a link to the contact page.
The center region has the main content for the page. It is different for each page.
Let’s open up the HTML for a page, and see how it is organized.

Figure 10. HTML organization
Inside the body tag are the four regions. Each has each own div. The colors match the ones in Figure 8.
Figure 10 uses code adapted from the liquid layout in the page layout lesson. The right region was removed, and widths, margins, and padding adjusted.
There’s some more HTML at the start and end of the page. The code at the start gives meta data like title, loads CSS and JavaScript files, and includes any page-specific CSS and JavaScript. The code at the end of the page just closes the body and html tags, although it might do more on other sites.
The HTML for a page is not stored in one file. A key point to remember is that the HTML in Figure 10 is assembled by PHP code.
The HTML is broken up into pieces. Most of the pieces are shared by all pages. The header, for example, is the same across the site (apart from adjusting file paths). The only thing that is completely different for each page is the content.
That’s what gives us the Big Win. There will be one file containing the HTML for the header, no matter how many pages are on the site. 100 pages? One header file. 10,000 pages? One header file.
Change that one file, and every page on the site changes. All 100. Or 10,000. A big productivity win.
Where are we? You’ve seen:
Let’s see what the site’s directory tree looks like.
Here it is:

Figure 11. Site directory tree
The root directory of the site just has two files: index.php and contact.php. All of the other files are in directories.
There is a directory for each major part of the site in Figure 1.
Why create a directory for each part of the site? This is another example of how Webers think about productivity. Suppose a user sends this email:

Figure 12. Email about spelling error
We want to be able to fix that error quickly and easily. Notice how easy it is to find the file with the error. All the articles are in the articles directory, so go there. The names of the files match the titles of the articles, so we open the file playing-with-dogs.php.
On the other hand, suppose we’d put all of the files in one directory, and named them things like file17.php. It would be harder to the file with the spelling error.
So the organization in Figure 11 gives us another productivity win. W00f!
OK, back to the files. Here is the tree again.

Figure 11 (again). Site directory tree
All of the shared files are in library. The file dogsite.css is a site-wide CSS file, with the colors, fonts, page layout style rules, etc. dogsite.js has the JavaScript code for the nav bar image switching.
The .inc files contain the HTML pieces for each page. There’s one file for each chunk in Figure 10:
start_page.inc)header.inc)left_nav.inc)footer.inc)end_page.inc). We’ll look at the code for each one in a moment.
The rest of the files in library are images for the header and the nav buttons.
Now let’s open up /index.php (the home page), and look at the PHP. Here is the entire code:
<?php //Path from this page to the site root. $path_to_root = '.'; //Title of this page. $page_title = 'Welcome'; require $path_to_root . '/library/start_page.inc'; require $path_to_root . '/library/header.inc'; require $path_to_root . '/library/left_nav.inc'; ?> <div id="center_region"> <h1>Welcome</h1> <p>See some <a href="dog-profiles/index.php">dogs</a>.</p> <p>Read an <a href="articles/index.php">article</a>.</p> </div> <?php require $path_to_root . '/library/footer.inc'; require $path_to_root . '/library/end_page.inc'; ?>
Figure 13. PHP for /index.php (the home page)
Line 2 is a comment. Comments begin with //.
Line 3 sets the variable $path_to_root. It contains the path from this file to the site root. /index.php is already at the root, so the variable is set to '.', which means “the current directory.”
Line 5 sets the variable $page_title to, well, the page title. This is used in the title tag, as we’ll see.
Lines 6 to 9 insert chunks of HTML. start_page.inc (line 6) goes down to the body tag. header.inc (line 7) is the page header. left_nav.inc (line 8) is the nav bar.
Line 9 ends the PHP code. Regular HTML follows.
Lines 10 to 14 are the main content of the page, in the center region. This is what varies the most across the pages of the site.
Line 15 starts PHP mode again. Line 16 inserts footer.inc, with the HTML for the page footer. Line 17 inserts end_page.inc, with the HTML to close the body and html tags.
Let’s have a look at /dog-profiles/renata.php, the page showing Renata’s profile. Here’s what it looks like in a browser:

Figure 4 (again). Dog profile
Here’s the code.
<?php //Path from this page to the site root. $path_to_root = '..'; //Title of this page. $page_title = 'Renata'; require $path_to_root . '/library/start_page.inc'; require $path_to_root . '/library/header.inc'; require $path_to_root . '/library/left_nav.inc'; ?> <div id="center_region"> <h1>Dog profile: Renata</h1> <p>Here is Renata.</p> <p><img src="renata.jpg" alt="Renata"></p> <p><a href="index.php">Back to the dog list</a></p> </div> <?php require $path_to_root . '/library/footer.inc'; require $path_to_root . '/library/end_page.inc'; ?>
Figure 14. PHP for /dog-profile/renata.php
Most of it is the same as the code for /index.php, in Figure 13. Let’s look at the differences.
Line 3 has the path to the root. /dog-profile/renata.php is in a subdirectory, so its path is “..”.
Line 5 has the page title. It is different, of course.
The content for the center region starts at line 10. That’s completely different from page to page, of course.
And that’s it. Those are the only differences.
Notice how easy it is to create a new page. Copy one of the existing pages, change the root path and title, and add the unique content. The header, footer, and nav bar are all set up.
This is another productivity gain. Creating new pages just got a lot simpler.
Let’s look inside the included files.
Here’s start_page.inc, the HTML up to the body tag (see Figure 10).
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><?php print $page_title; ?> | The Dog Site</title>
<link rel="stylesheet" type="text/css" href="<?php print $path_to_root; ?>/library/dogsite.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
var path_to_root = '<?php print $path_to_root; ?>';
</script>
<script type="text/javascript" src="<?php print $path_to_root; ?>/library/dogsite.js"></script>
</head>
<body>
Figure 15. start_page.inc
The page title is added in line 5. The root path is used in lines 6, 9, and 11. The rest is just plain HTML.
Here’s the code for header.inc.
<div id="top_region">
<div id="logo_images">
<img src="<?php print $path_to_root; ?>/library/logo.png" alt="Logo">
<img alt="The Dog Site" src="<?php print $path_to_root; ?>/library/header.png">
</div>
<div id="subtitle">Bringing you happiness since last week</div>
</div>
Figure 16. header.inc
The root path is used on lines 3 and 4, to get the right paths to the image files.
Here is left_nav.inc.
<div id="left_region">
<ul class="vertical_menu">
<li>
<a href="<?php print $path_to_root; ?>/index.php">
<img id="home_button" src="<?php print $path_to_root; ?>/library/home_up.png" alt="Home">
</a>
</li>
<li>
<a href="<?php print $path_to_root; ?>/dog-profiles/index.php">
<img id="dogs_button" src="<?php print $path_to_root; ?>/library/dogs_up.png" alt="Dogs">
</a>
</li>
<li>
<a href="<?php print $path_to_root; ?>/articles/index.php">
<img id="articles_button" src="<?php print $path_to_root; ?>/library/articles_up.png" alt="Articles">
</a>
</li>
</ul>
</div>
Figure 17. left_nav.inc
Each link and image needs to be adjusted for the root path.
Here’s footer.inc.
<div id="bottom_region"> <p>© 2010 Nobody at all | <a href="<?php print $path_to_root; ?>/contact.php">Contact</a></p> </div>
Figure 18. footer.inc
The path to the contact page needs the root path. Nothing else changes.
Hey, wait a minute.
What’s up?
Well, I’m just thinking. This seems awfully complex. Is it worth the effort?
Yes, I agree. I’m not sure I’ll like PHP.
Good point. Let’s talk about that a bit.
Have a look at the directory tree again.

Figure 11 (again). Site directory tree
There are lots of pieces here. Look at the library directory. There are fifteen files in there! Ack!
But let’s look more closely. Six of the files are button images. Another two are images for the header region. Nothing to do with PHP there, just regular images.
The files dogsite.css and dogsite.js have nothing to do with PHP either. They’re just regular things we saw in ClientCore.
What about the five .inc files? They are mostly plain HTML. There is only one PHP statement in them: print. As in:
<?php print $path_to_root; ?>
In fact, there is only one other type of PHP statement in the entire site. That’s require, as in:
require $path_to_root . '/library/start_page.inc';
The complexity comes not from the PHP. It comes from the underlying complexity of HTML, CSS, and JavaScript itself.
Web sites are complex. There is no doubt about it. That’s why people pay other people to create them.
The complexity comes not from the fact that any one thing is complex. But even in a small site, there are dozens of things to get right. Each of those small things combines to make a complex whole.
Don’t feel bad if this seems messy to you. It is messy. There’s a lot going on. But it’s your mastery of this that will make you a valuable employee, consultant, or whatever.
And one more thing about complexity. We added the PHP not to make the Web site look better. We added it to make it easier to change. Not only do we have to complexity of HTML, CSS, JavaScript, jQuery, and PHP. We have the complexity of work processes as well.
Ack! It’s enough to drive you to catnip.
There are some big productivity wins here. Let’s review.
We want a new page, like a new article. We just copy /index.html (or another of the PHP files), change the root path and the title, and add the new content. We just work on what is unique on that new page. We don’t even have to think about the header, nav bar, etc.
Remember the email we looked at earlier, the one that told us about the spelling error? We could find the file to change very easily, because:
This has nothing to do with PHP. It’s just another example of how Webers think. Organize now to reduce problems later.
We can change the entire site by changing one file. For example, let’s say we wanted to add a new section to the site, for products. We add a new button to left_nav.inc, and every page in the site has the new button!
This is a Big Win. Your employer or client will be glad they hired you, because you give good value for money.
In this lesson, you:
Time to do some more exercises.
Create a Web site about old things, like this one. Use the same method we used in the complete template system.
Download the images from the site.
You can download a zip file of my solution, but try it yourself first.
Upload your solution to your server. Put the URL below.
(Log in to enter your solution to this exercise.)