The Ultimate Website Pt. 1
Published Wednesday, March 29, 2006 in (X)HTML, CSS, PHP, Web Standards
Please note: "Ultimate" is only ultimate for so long. And I don't exactly do it like this anymore, but I still believe it's an OK beginners-guide to building a dynamic, easy-to-update web site.
After having programmed PHP, (X)HTML and CSS for a few years now, I've finally come up with a website-structure that I'm satisfied with. A website that uses valid markup, dynamic PHP and a completely CSS-driven design. So it can be used over, and over again with very little changes.
This three part article will try to explain everything, from setting up directories to the final website.
It is aimed at semi-beginners who wish to learn some basic PHP, and how to program with web standards and CSS.
If you don't know any PHP, CSS or XHTML i suggest you google your way to some beginner-tutorials before you continue reading.
Setting up your directories
This, of course, is a matter of taste, but in order for the rest of this article to work without problems some of this is recommended.
I normally have four dirs on my average website;
- content/
for all content to be included by index - css/
all CSS, including decorative images (used only for design) - img/
all other imagery - inc/
for PHP-files that are not content, like functions and such
And then, also in root of course, my index.php.
The index file
Index.php consists of everything that isn't contents (or sub contents), that is; header, navigation, content-container, sub content-container and footer. I normally write the XHTML first, without thinking too much about the PHP to come.
First in every HTML document there must be a DOCTYPE. Since we're programming XHTML 1.0 Strict, here's the DOCTYPE you should put on line 1 in your index.php file.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
If you wish to know more about DOCTYPES, here's a really good article.
After this, of course, comes <html>, <head> and then <body>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<meta name="author" content="A. Name" />
<meta name="keywords" content="respect" />
<meta name="description" content="A. Name's personal website" />
<link rel="stylesheet" type="text/css" href="css/default/style.css" />
<title>A. Name's personal website</title>
</head>
<body>
</body>
</html>
That's pretty straight forward I hope, but it's what's inside <body> that's interesting.
<body>
<div id="site">
<div id="header">
<h1><a href="./" title="Home">A. Name's personal website</a></h1>
<p>A website about a lot of stuff that A. Name thinks is interesting</p>
</div>
<hr />
<div id="nav">
<h2>Navigate</h2>
<ul>
<li><a href="?p=home" title="Home / Latest news" class="selected">Home</a></li>
<li><a href="?p=portfolio" title="My work">Portfolio</a></li>
<li><a href="?p=about" title="About me and contact">About</a></li>
</ul>
</div>
<hr />
<div id="content">
</div>
<hr />
<div id="sub-content">
</div>
<hr />
<div id="footer">
<ul>
<li><a href="#header" title="Top of page">Top</a></li>
<li><a href="http://www.mozilla.com/firefox/" title="Get Firefox!">Firefox</a></li>
<li><a href="http://validator.w3.org/check?uri=referer" title="Valid XHTML 1.0 Strict">XHTML</a></li>
<li><a href="http://jigsaw.w3.org/css-validator/check/referer" title="Valid CSS">CSS</a></li>
</ul>
<p>Copyright © 2006 <a href="mailto:a.name@gmail.com" title="Drop me a line (opens your mail-client)">A. Name</a></p>
</div>
</div>
</body>
I like to separate the main parts of the website with <hr />s, it looks nice for people without CSS, and I never EVER use <hr /> anywhere else, so I just display: none; on all of them later in my CSS-file.
As you can see, every main part also has its own containing <div>. This makes it easy to style every part of the website, without the use of too many ID's or classes. Some may argue that #nav (and others for that matter) are useless because you can style the <ul> just as easily, but I think the added styling you can do is worth it.
In #header, I've put the name of the website in a <h1> with a link back to home, and also the website slogan (if there is one) in a <p>. Both of these are normally replaced with images using CSS later on.
In #nav I obviously use a list for the menu, but also a heading saying "Navigate" so you can easily see where the navigation is. As you can see, the links are pointing to ?p=home, ?p=portfolio and so on. This is so it will work with the PHP later on, more about that later.
The #content and #sub-content-divs are empty at the moment, that's where we'll include all the contents later on using PHP.
And finally, in the #footer I put some standard links, showing off the fact that it's a valid XHTML website :), and encouraging people to download Firefox.
Next we'll add the PHP that is used for the navigation to function properly, and for all the contents to be included. If you don't know any PHP I suggest you read a beginners tutorial on it before continuing. But it's not necessary to know PHP to follow this article.
First of all, we'll add some PHP to the top of index.php that takes care of including some other PHP files, like database-connection and functions (more on this later). It also makes sure that you can't include anything but files in the content/ directory, and if $_GET['p'] isn't set, it sets it to its default.
<?php
// Include functions
include("inc/func.php");
// So we can call header() from anywhere
ob_start();
// Set p if it isn't set
$_GET['p'] = (isset($_GET['p'])) ? $_GET['p'] : "home";
// Remove '../' and '..' from 'p' so nothing bad can be included
$_GET['p'] = str_replace("..", "", str_replace("../", "", $_GET['p']));
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
That's how your 1st few lines should look now.
Now we're gonna make the navigation illustrate which page we're on, using some simple PHP for checking which one should have class="selected".
<div id="nav">
<h2>Navigate</h2>
<ul>
<li><a href="?p=home" title="Home / Latest news"<?php echo ($_GET['p'] == "home") ? " class="selected"" : ""; ?>>Home</a></li>
<li><a href="?p=portfolio" title="My work"<?php echo ($_GET['p'] == "portfolio") ? " class="selected"" : ""; ?>>Portfolio</a></li>
<li><a href="?p=about" title="About me and contact"<?php echo ($_GET['p'] == "about") ? " class="selected"" : ""; ?>>About</a></li>
</ul>
</div>
That code checks whether the value of 'p' is the same as the one the link is pointing to. So, if 'p' has the value 'home', then the link pointing to '?p=home' will have class="selected".
Now comes the content. All you need to do here is to check whether the file 'p' is pointing to really exists, and if so include it. If not, include a 404-page. There is no risk of including any page other than those in content/, because we took care of that before with str_replace, remember?
<div id="content">
<?php
if(is_file("content/" .$_GET['p'] .".php"))
{
include("content/" .$_GET['p'] .".php");
}
else
{
include("content/404.php");
}
?>
</div>
And all that's left to be done is to include some sub-content in, you guessed it, #sub-content
<div id="sub-content">
<?php
include("content/sub/poll.php");
include("content/sub/search.php");
?>
</div>
Remember that for this code not to produce any errors, all of these files we include needs to really exist. At the moment they don't have to contain anything (although putting a heading in each document makes it nicer, and easier to see what's where), as they are only used as examples. I will not explain how to create a poll, search-function or anything like that in this article.
Here's a zip with the whole page-structure and all the source-code so far.
And here's the dir-structure and complete code for index.php.
Dir structure
I've also added the files that are needed.
- content/
- sub/
- poll.php
- search.php
- sub/
- css/
- default/
- style.css
- default/
- img/
- inc/
- func.php
Index.php
<?php
// Include functions
include("inc/func.php");
// So we can call header() from anywhere
ob_start();
// Set p if it isn't set
$_GET['p'] = (isset($_GET['p'])) ? $_GET['p'] : "home";
// Remove '../' and '..' from 'p' so nothing bad can be included
$_GET['p'] = str_replace("..", "", str_replace("../", "", $_GET['p']));
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<meta name="author" content="A. Name" />
<meta name="keywords" content="respect" />
<meta name="description" content="A. Name's personal website" />
<link rel="stylesheet" type="text/css" href="css/default/style.css" />
<title>A. Name's personal website</title>
</head>
<body>
<div id="site">
<div id="header">
<h1><a href="./" title="Home">A. Name's personal website</a></h1>
<p>A website about a lot of stuff that A. Name thinks is interesting</p>
</div>
<hr />
<div id="nav">
<h2>Navigate</h2>
<ul>
<li><a href="?p=home" title="Home / Latest news"<?php echo ($_GET['p'] == "home") ? " class="selected"" : ""; ?>>Home</a></li>
<li><a href="?p=portfolio" title="My work"<?php echo ($_GET['p'] == "portfolio") ? " class="selected"" : ""; ?>>Portfolio</a></li>
<li><a href="?p=about" title="About me and contact"<?php echo ($_GET['p'] == "about") ? " class="selected"" : ""; ?>>About</a></li>
</ul>
</div>
<hr />
<div id="content">
<?php
if(is_file("content/" .$_GET['p'] .".php"))
{
include("content/" .$_GET['p'] .".php");
}
else
{
include("content/404.php");
}
?>
</div>
<hr />
<div id="sub-content">
<?php
include("content/sub/poll.php");
include("content/sub/search.php");
?>
</div>
<hr />
<div id="footer">
<ul>
<li><a href="#header" title="Top of page">Top</a></li>
<li><a href="http://www.mozilla.com/firefox/" title="Get Firefox!">Firefox</a></li>
<li><a href="http://validator.w3.org/check?uri=referer" title="Valid XHTML 1.0 Strict">XHTML</a></li>
<li><a href="http://jigsaw.w3.org/css-validator/check/referer" title="Valid CSS">CSS</a></li>
</ul>
<p>Copyright © 2006 <a href="mailto:a.name@gmail.com" title="Drop me a line (opens your mail-client)">A. Name</a></p>
</div>
</div>
</body>
</html>
In part 2 I will explain some basics of designing with CSS. You will learn how to position elements, replace text with images, and most of the basic CSS stuff that's nice to know.
Part 3 will finish everything up, add a style-switcher (so you can have different styles like CssZenGarden) and some more useful stuff.






Comments
11 comments so far, why don't you post one too?
Wednesday, March 29, 2006 | View all comments by Zajmon
Kanon, du har lyckats där med <hr /> för browsers som inte stödjer css. GJ
Friday, October 13, 2006
Varför inkluderar vi func.php i början av sidan? Det beskrivs inte i artikeln vad vi ska lägga in i den filen för kod.
Saturday, October 14, 2006 | View all comments by Andreas
Det är meningen att jag ska ta upp det i del 3. Om jag nu orkar skriva den nån gång.Men i func.php ligger diverse bra funktioner som tex tar hand om att snygga till text m.m.
Thursday, October 19, 2006 | View all comments by Erik Andersson
Den här artikeln har verkligen hjälpt mig med mitt kodande! Utan den skulle jag inte veta något!
Thursday, October 19, 2006 | View all comments by Ante
Hehe fan vad bra
Tuesday, October 31, 2006
Ett inställt samlag är också ett samlag /Bördan
Tuesday, October 31, 2006 | View all comments by Tobiiazz
Mycket bra, använder det numera till min hemsida. Är tänkt att jag ska införa en style switcher
Friday, March 16, 2007
Skitbra artikel, ska läsa mer imorron, och försöka bygga om min sida till semantisk xhtml. Du är riktigt duktig.
Friday, March 16, 2007 | View all comments by Andreas
Tack! Kul att höra.
Wednesday, May 09, 2007
Skitbra! Hur ska jag gå till väga om jag vill lägga in ett bildgalleri på sidan tex http://www.plogger.org/. Och få det att öppnas i content diven?. Det går ju inte att lägga i content mappen.
Thursday, May 10, 2007 | View all comments by Andreas
Jag har tyvärr ingen aning hur Plogger är gjort, men i de allra flesta fall används något liknande index-include eller head/foot system.
Det du får göra är att ta koden från din sidas head/foot och placera i Ploggers head/foot, samt importera alla stylesheets.
Då kommer Ploggers huvud och fot se likadan ut som resten av sidan.
Du kan däremot inte inkludera den direkt i content-diven. Plogger har förmodligen sin egen <html><head>etc så det skulle bli galet. Och förmodligen skulle mkt annat gå fel också.
Men leta efter en head/header.php samt foot/footer.php och prova lek lite i dem.