Skip Site Navigation «

Anatomy Class

vnav«labs«PHP«body
Element

an (abstract) artifact that is one of the individual parts of which a composite entity is made, especially a part that can be separated from or attached to a system

(paraphrased)
Synonym (3): component
WordReference.com

The whole is greater than the part.

Euclid’s Elements, Book 1, Common Notion (Axiom) 5.
headmap.org

Contents

  1. Introduction
  2. Lab Progress
  3. The body() Function
  4. Site Structure
  5. Adding a New Resource
  6. The navs() Function
  7. The content() Function
  8. 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:

Content-type: application/xhtml+xml; charset=UTF-8 <?xml declaration?> <!DOCTYPE declaration> <html> <head> <title>My Document</title> ... </head> <body> <p>My content...</p> </body> </html>

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

  1. body() — opens the <body> element
  2. navs() — populates the navigation menus
  3. content() — 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:

layout

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:

Table laz.dir: Describe structure.
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
Table laz.file: Describe structure.
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
Table laz.media: Describe structure.
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
Table laz.media: Selected data.
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):

  1. fid — file ID
  2. mid — media ID
  3. did — directory ID
  4. pid — parent ID

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:

  1. Insert a new entry into the database in the correct position
  2. Copy a template file into the correct directory
  3. Edit the template to add the content for the help resource
  4. 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>:

<div id="hnav"> <div id="menu"> $menu </div> </div> } // body()

You’re welcome to study the source code to the body() 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:

$uri = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; $uri = urlencode($uri);

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:

<div id="contents"> <h1>$h1</h1> <div id="pebbles" title=" Pebbles to find your way Home "> $path </div> } // content() // markup the content here

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

Last updated: Friday, October 31st, 2008 @ 2:34 PM EDT [2008-10-31T18:34:36Z]   home

(c) 2008-2010, Douglas W. Clifton, loadaveragezero.com, all rights reserved.