«
Anatomy Class
Contents
- Introduction
- Lab Progress
- The
body()Function - Site Structure
- Adding a New Resource
- The
navs()Function - The
content()Function - PHP Labs Navigation
Introduction
Just because we’re moving further away from the low-level aspects of a valid
XHTML document: HTTP headers, the XML and DTD
declarations (the prolog) and the <head> element, doesn’t mean it’s time to get lazy.
The focus remains on the structure and modularization of an XHTML document and how you can
use PHP to divide these components into discrete blocks,
and then quickly bind them back into a complete Web page.
While the previous articles in this series covered topics that are important, crucial even,
they remain largely concealed from your audience. But the moment you open the <body> tag this
quickly changes. So naturally CSS will play a major role in this lab, and with
it the original intent to separate document structure from layout and presentation. However,
it is not meant to be a tutorial on CSS, any more than this series is meant to be a tutorial on
PHP programming. See my layout article in the CSS Labs for some background of how this
site is designed. You can use any design you like and still apply these principles to it.
My goal is to demonstrate the application of these concepts, and one example (this Web site) of
the end result. You are free to use as little or as much of it as you want, or you can just
read along and hopefully learn something.
The <body>, like the <head> element in the last article, is not really elemental at all, at
least not in an atomic sense. Both are contained by the root element <html>. Or rather, are
descendant (children) from it as defined by the DOM. Since both are also containers for
other objects, molecular would probably be a better metaphor.
Lab Progress
Let’s recheck our minimal XHTML document framework to date:
Now we’re getting somewhere! But I must warn you, it’s a little deceiving.
As of this writing, my PHP body.php module library has three functions (actually four,
but we’ll save the last one for later):
body()— opens the<body>elementnavs()— populates the navigation menuscontent()— opens the content<div>element
The body() Function
Just when you thought I’d run out of surprises this function begins by printing the opening
<body> tag and setting the id attribute value to my domain name.
The global $page hash variable now reappears and if it has a value indexed by the
string "class", then I set a class with that value also:
<body id="loadaverageZero" class="body">
The question I suppose is what would motivate me to do this? The first case is a
DOM/ECMA/Javascript question and this series is
about server-side programming, not client-side. The short answer is it allows me
to retrieve the <body> node in one function call and alter it or its children
nodes quickly. That’s all I have to say about that for now. The second case is more
interesting: By setting rules in my root.css stylesheet that match the current
page I can display an active
page background color on menus. It’s useful
in other ways, but let’s move on.
I’ll now open the <div> tags that are the basic layout elements of the design.
To illustrate this, the figure below is a basic mockup of the site with these major
visual/structural tags:
As you can see, #canvas is the outermost parent container; I then add the
#header <div> and insert the logo (masthead) which by convention is linked to
my home page.
At this point a decision had to be made, either to generate the horizontal menubar as part
of the body() function, or save it for the more semantically correct navs()
function. Since visually and structurally this element is part of the header I opted to
implement it here.
Site Structure
This forces me to interject again, otherwise I’ll lose you. Unfortunately, at the time of this writing the MySQL Labs series remains incomplete. I hope to come back and update this page before long and give you links to other pages that will elaborate on these features. In the meantime I’ll give you a brief overview.
In large part the structure of this site is stored in a MySQL database. Notice I said site, not document! What I’ve done is designed a virtual filesystem for the path portion of a URI to each resource on the site. Rather than relying on system calls on the host machine, I can use these tables to quickly locate any resource by traversing these tables. It also allows me to build a sub-path for each step along the way, including properties that are stored for these locations.
Each directory (folder) and file (resource) is registered into the database. Each resource (PHP script, stylesheet, javascript...) is also linked to a media table. I’ll get to that in a sec. Here is a small subset of the schema:
| mysql> describe laz.dir; | |||||
|---|---|---|---|---|---|
| Field | Type | Null | Key | Default | Extra |
| 4 rows in set (0.00 seconds) | |||||
| did | tinyint(3) unsigned | Yes | PRI | NULL | auto_increment |
| pid | tinyint(3) unsigned | No | 0 | ||
| name | char(16) binary | No | |||
| title | char(32) | No | |||
| mysql> describe laz.file; | |||||
|---|---|---|---|---|---|
| Field | Type | Null | Key | Default | Extra |
| 5 rows in set (0.00 seconds) | |||||
| fid | smallint(5) unsigned | Yes | PRI | NULL | auto_increment |
| did | tinyint(3) unsigned | No | 0 | ||
| mid | tinyint(3) unsigned | No | 0 | ||
| name | char(16) binary | No | |||
| title | char(64) | No | |||
| mysql> describe laz.media; | |||||
|---|---|---|---|---|---|
| Field | Type | Null | Key | Default | Extra |
| 4 rows in set (0.00 seconds) | |||||
| mid | tinyint(3) unsigned | Yes | PRI | NULL | auto_increment |
| ext | char(8) | No | |||
| major | enum('application','audio'... | No | application | ||
| minor | char(32) | No | |||
| mysql> select * | |||
|---|---|---|---|
| mysql> from laz.media | |||
| mysql> where ext in ('xhtml','php','html','css','png','jpg') | |||
| mysql> order by major,minor; | |||
| mid | ext | major | minor |
| 6 rows in set (0.00 seconds) | |||
| 7 | php | application | x-httpd-php |
| 1 | xhtml | application | xhtml+xml |
| 12 | jpg | image | jpeg |
| 11 | png | image | png |
| 18 | css | text | css |
| 16 | html | text | html |
Notice I’ve selected a few rows from the media (types) table, which should be self-explanatory
now. So, each resource on this site has an entry in the file table, and is also
linked to the dir (folder) and the media tables. Here is a
summary of these links (IDs, or a key
in a RDBMS):
fid— fileIDmid— mediaIDdid— directoryIDpid— parentID
Each directory knows where it lives
in the system via a parent ID,
unless that ID happens to be null, in which case you are at the root of the system. Only one
resource exists there — the home page.
FAQ: What is this root
thing you’re always
referring to? The root (node) of a hierarchical tree structure is one that all
other nodes are spawned from, it has no parent. Under Unix-style operating systems,
root or the superuser, has all privileges and all other user accounts are
created from it. The root of an XHTML document is the <html> element and the same holds
true for the DOM.
Adding a New Resource
So, the point of all this is pretty simple, it allows me to automate a number of similar tasks.
You may have noticed if you’ve taken a moment to view the PHP source code to one of these articles
that I always open each script by assigning a value to the $fid variable (or $did in the
case of a directory index). These variables uniquely identify each document. The pebbles (breadcrumb)
interface is generated from this, as are some other things. In a similar way the horizontal menubar is
automatically created.
Let me give you an example that should illustrate how powerful this set-up is. Say I want to add a help option to the menubar (which I will be, hopefully soon). To do this I will:
- Insert a new entry into the database in the correct position
- Copy a template file into the correct directory
- Edit the template to add the content for the help resource
- Add a rule to my stylesheet to hightlight the menu option
And just like that the Help document is complete. The breadcrumb interface is automatically generated and the menu option is active when a visitor accesses the help page, Likewise the menu item is instantly available on every pre-existing and subsequent new page on this Web site. If that isn’t a Eureka Factor, I don’t know what is!
Okay: Maybe not just like that
since it took me almost
a week to complete step #3!
So the body() function concludes by issuing a SQL select/join
query to build the $menu items and then prints the #hnav <div>:
$menu
</div>
</div>
} // body()You’re welcome to study the source code to the body() function
The navs() Function
This function, like the previous one does not require any parameters. Unlike the previous
one the $page global hash is unused. Neither are any other globals. What it does
do is generate the entire #left sidebar starting with the vertical navigation
menus. Just like the body() function these are populated from the same set of tables
as explained above. I’ll leave the gory details on that for the MySQL Labs.
Once I’ve finished the menus I set up the URIs to all those 80x15 pixel buttons,
notably the W3C validators and the lynx and source view links since they must be
generated on a per-page basis. This is easily accomplished via PHP’s $_SYSTEM hash
like this:
It’s important to filter $uri through the PHP urlencode() function since we must pass
it to the validators as a query string variable. Refer to the XHTML source code to this page
for additional details. The resulting string for this page, quite literally is:
http%3A%2F%2Floadaveragezero.com%2Fvnav%2Flabs%2FPHP%2Fbody.php
The usual Powered by
(or maybe not, I like to give nods where they’re due) links
follow. Finally, I have a list of favicon
links to places I find
interesting for various reasons. I then close the #left <div> container
and the function is complete.
The content() Function
Okay, as you might expect this is where the real action is. But don’t start submitting all
those wonderful articles you wrote for me quite yet. This function does one very simple thing,
which is open the #content <div>, and another not so simple thing, which is
generate the pebbles interface.
Recall that the very first thing I do at the top of each script is ID the resource.
Recall also that the MySQL table structure I’ve designed is based on a tree structure.
A resource is referred to as a leaf
node, or furthest away from the root.
Similar in that a root node has no parent, a leaf node has no child —
it terminates the path from root to itself. A directory is not
a terminating node, it’s a container for resources (leaf nodes) or possibly other
containers (directories).
The next step is to immediately include the pebbles.php library module which calls
the pebbles() function.
What this function does is traverse the path from the resource node back to the root, and along the way collecting each node’s path (and properties), pushing them onto a stack. Although not a true depth-first search, since I’m not searching the entire tree (Site Map anyone?), it achieves my goal of building a suitable data structure needed to create the pebbles interface.
To help you understand how this works I’ve created this demonstration. And by all means, try the pebbles interface at the top of each page to navigate the site.
To complete the function, I open the content <div>, add the headline and then the pebbles
path
back to the root (home) of the relative filesystem:
The next article has little to do with document structure, but introduces a toolkit of PHP functions that can make your life easier when adding the content to your site. At least they do mine. Read on...




























































































![MySQL [I own this title!]](/img/books/0672326736.jpg)

