Main Page Content
Write Once Class Layout The Html Heresy
Have you ever wondered what is the price to pay for Evolution? I mean upgrading your pages to reach the current W3C standard, every 6 months. When xHTML went recommended I asked myself :: "What would you do, my dear friend, if you have 2 handfuls of sites running and your clients call, asking that the pages should be standard compliant tomorrow? They would find my cold body on my chair, my face buried in the monitor up to the neck." Then I found a solution...and it may be yours now , ) I searched if it was possible to build an engine which would ouput pages undependent of HTML code - an engine that would receive instructions, process them through the current lexicon you give it (i.e. : HTML4.0/xHTML...), translate, and serve. I found an article about class.layout in phpBuilder. First, when I saw this, I yelled :: "HERESY!" The next day, I had the strange feeling that it could have missed somthing important, and re-read it. I had the solution, I found the Grail! Class.layout sets up tag constructors, functions whose variables are tag attributes and their values. After a little tweaking, this class was fully xHTML compliant, and if my pages had used it, each one would have been xHTML complient in half an hour. Let's go through the principles of this class, then we'll see how to modify it, and how to built a php page that ouputs pages with browser-specific HTML. I would advice you to take a look at the phpBuilder article first, as i don't want to paraphrase it, and want to avoid making this article too awfully long, and as i go deeper into concepts i introduced in my precedent article, you should perhaps get a look on it. Beware, I jump into the serious things right now...I warned you, read the phpBuilder article first , )
How it works ::
Let's analyse the text constructor. class Text extends HTMLBase { var $classname = "text"; var $str; function Text($s,$a = "") { // gets the attributes, then they are stocked into 'settings' // by the parent constructor magic. Trust me. $this->setparam($a); //gets the text string $this->str = $s; } function printit() { echo "<FONT". $this->settings . ">"; echo $this->str; echo "</FONT>"; } }
Use it. insert($where_you_want, text("php-foo", array("face"=>"arial","color"=>"lime", "id"=>"test")));
What it does ::
It outputs in the element $where_you_want (predefined element that could be a table, a layer, a div...) the tag container <FONT> and the variables you gave it. <FONT FACE="arial" COLOR="lime" ID="test">php-foo</FONT>
ok?How to modify it ::
I'm no phpwizz, i'm no OOPguru, I only took a deep breath and experimented. The example will be how to make a xHTML defined page based on the standard HTML class. The html newhtml() constructor :: function newhtml(&$w,$a = "") { $w = html($a); } ... function html($a = "") { $na = md5(microtime()); $GLOBALS["$na"] = new Html($a); return $na ; } ... class Html extends HTMLBase { var $classname = "html"; function html($a = "") { $this->setparam($a); } function printit() { echo ><!DOCTYPE HTML PUBLIC \>-//W3C//DTD HTML 4.0 Transitional//EN\>>>; echo ><HEAD>"; $this->printheader(); echo "<HEAD>settings . " >"; $this->printchild(); } function printheader() { if (is_array($this->children)) { reset($this->children); while ( list(,$ch) = each($this->children) ) { if ( getclass($ch) == "wheader" ) { $GLOBALS["$ch"]->printit(); } } } } }
To build a newxhtml() func... function newxhtml(&$w,$a = "") { $w = xhtml($a); } ... function xhtml($a = "") { $na = md5(microtime()); $GLOBALS["$na"] = new Xhtml($a); return $na ; } ... class Xhtml extends HTMLBase { var $classname = "xhtml"; function xhtml($a = "") { $this->setparam($a); } function printit() { echo "<? XML VERSION=\"1.0\" ENCODING=\"UTF-8\" ?>"; echo "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"DTD/XHTML1-strict.DTD\">"; echo "<HEAD>"; $this->printheader(); echo "<HEAD>settings . " >"; $this->printchild(); } function printheader() { if (is_array($this->children)) { reset($this->children); while ( list(,$ch) = each($this->children) ) { if ( getclass($ch) == "wheader" ) { $GLOBALS["$ch"]->printit(); } } } } }
EASY! Look Ma, I know OOP !!!!!These tweakin's were essential, cuz' the open-sourced version of class.layout was very restrictive. You couldn't just output a serie of tags, the part of a page, you were obliged to construct your page like a block. Now you know how to tweak it, you can create your constructors. I added a newsnip() which outputs only the tags you insert()...
Now, let's see the REALLY serious things. I discovered that I can use this class to create pages which use the fundamentals of CSS...but on STEROIDS !! With php, you can define veriables that hold any string you want, ok? Let's see some vars. $mailto = "you@your.address"; $bckgrnd = "background.gif";
Okay, quite simple stuff. Now, i want to trim down all the redundancies in my code. Say I use several lines like this in my code :: insert($w,$title = table(array("width"=>"100%", "border"=>"0", "cols"=>"2")));I could define
$basic_table = array("width"=>"100%", "border"=>"0", "cols"=>"2"); ... insert($w, $title = table($basic_table));Do you feel the scheme?
i.e. a menu box ::
<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="1" BORDERCOLOR="#CCCCCC" HEIGHT="10" WIDTH="76" ID="menu"> <TR> <TD WIDTH="71"> <A HREF="/blitzblog.php3" onMouseOver="chgcolor(2,1); window.status='daily memes harvest/net hype of the day'; return true" onMouseOut="chgcolor(2,1,1); window.status=''; return true" ID="linkk" TITLE="'daily memes harvest/net hype of the day'" >blitz|blog</A> </TD> <TD WIDTH="5"> <A HREF="/blitzblog.php3" onMouseOver="chgcolor(2,1); window.status='daily memes harvest/net hype of the day'; return true" onMouseOut="chgcolor(2,1,1); window.status=''; return true" ID="linkk" TITLE="'daily memes harvest/net hype of the day'" >»</A> </TD> </TR></TABLE>
is translated to insert($menucell, $submenu = table($submenu_attr)); insert($submenu, $linkcell = cell($wdth1)); insert($linkcell, $blitzblog); insert($submenu, $gtcell = cell($wdth2)); insert($gtcell, $blitzbloggt);
With the variables defined :: $submenu_attr = array("bordercolor"=>"#CCCCCC", "height"=>"10", "cols"=>"2", "width"=>"76", "id"=>"menu"); $wdth1 = array("width"=>"71"); $wdth2 = array("width"=>"5");// This means that each of your menu boxes are defined by these 3 variables. //onto the links$altblitzblog = "'daily memes harvest/net hype of the day'"; if (cap == 3) { $blitzblog = anchor("/blogger.html", "blitz|blog", array("onMouseover"=>"chgcolor(2,1); window.status=$altblitzblog; return true", "onMouseout"=>"chgcolor(2,1,1); window.status=''; return true", "id"=>"linkk", "title"=>$altblitzblog ) ); $blitzbloggt = anchor("/blogger.html", "»", array("onMouseover"=>"chgcolor(2,1); window.status=$altblitzblog; return true", "onMouseout"=>"chgcolor(2,1,1); window.status=''; return true", "id"=>"linkk", "title"=>$altblitzblog )  ); }else { $blitzblog = anchor("/blogger.html", "blitz|blog", array("onMouseover"=>"window.status=$altblitzblog; return true", "onMouseout"=>"window.status=''; return true", "id"=>"linkk", "title"=>$altblitzblog ) ); $blitzbloggt = anchor("/blogger.html", "»", array("onMouseover"=>"window.status=$altblitzblog; return true", "onMouseout"=>"window.status=''; return true", "id"=>"linkk", "title"=>$altblitzblog ) ); }
My favorite topic...each browser got it's output! If i want a js to happen only where it is supported, i summon it here. It may seem excessive, but think that each of your menu boxes will only need the same code (with the appropriate links variables called), and that they will all change in ALL your pages if you tweak a variable in your definition page! Uber-CSS for all browsers as it is done server-side!examples ::
- the html output :: data.html
- the php source :: data.txt
- the definitions file :: def.txt
- the browser detection file :: browserdet.txt
- my class.layoutrevised :: class_layoutrevisited.txt
- if you want my data.inc :: data_inc.txt