Search In Site

20 June, 2013

How to Create Truly Skinnable Web Sites

Take your data and put it in an XML file
For example, a site's index page might look like this:<?xml version="1.0" encoding="UTF-8"?> <mySite page="index" title="Welcome to my site!"> <linkbar> <item type="link"> <uri>./faq.php</uri> <title>FAQ</title> <desc>Frequently Asked Questions about this site</desc> </item> <item type="form"> <action>./search.php</action> <method>post</method> <input type="text" name="search" maxlength="100"/> </item> <!-- other links --> </linkbar> <greeting> <para> Welcome to my site! </para> <para> Please check out all the sections. </para> </greeting> <news> <news-story> <date>November 29, 2001</date> <story>Some stuff happened.</story> </news-story> <news-story> <date>November 30, 2001</date> <story>Some more stuff happened.</story> </news-story> </news> </mySite>

Looks pretty simple, but it can be improved upon to make it even easier for us to maintain. Instead of adding a news story by manually editing the file, I'd like to pull the stories out of my database. That way, I can create a simple script to put my news in the database and then I can easily add news stories without having to FTP in to the server and edit the file.

We'll be using php's XSLT extension, Sablotron, to transform the XML file (discussed later on), so why not use its power to add dynamic content to the XML file also? It's easy to do. Just have php hold the XML data, pass it to Sablotron and have it pass the data to the XSL file. For example, to pull news stories out of a MySQL database and have it added to the XML file, we would do the following:
// code to connect to the database and pull the stories omitted for brevity. // $db_query holds an SQL query to pull news stories out of the database. $xsltArgs["stories"]="<news-story>"; while($row= mysql_fetch_array($db_query) { $date= $row["date"]; $story= $row["story"]; $xsltArgs["stories"].=" <date>$date</date> <story>$story</story>"; } $xsltArgs["stories"].="</news-story>";

$xsltArgs is an array. $xsltArgs["stories"] holds the XML for the news stories. This variable will be used later when the transformation takes place. If you want to add more dynamic data to your site, store it as XML in another slot of the array.

Now that we've created the XML file for the index page, we can create an XSL file that will be used by Sablotron to transform the XML file. Here is an XSL file that will transform the XML file into a simple XHTML web page.

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes" encoding="utf-8" method="xhtml"/> <xsl:template match="/"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>My Web Site - <xsl:value-of select="mySite/@title" /></title> <meta content="My homepage!" name="Description" /> <meta content="My, stuff, cool page" name="Keywords" /> <meta content="ALL" name="Robots" /> <meta content="Copyright 2001 Joe-Webmaster" name="Copyright" /> <meta content="Joe-Webmaster" name="Author" /> <link href="main.css" rel="stylesheet" type="text/css" /> </head> <body> <br /> <xsl:call-template name="linkbar" /> <br /> <xsl:call-template name="content" /> </body> </html> </xsl:template> <xsl:template name="linkbar"> <xsl:for-each select="mySite/sidebar/item"> <xsl:if test='@type="link"'> <a href="{uri}" title="{desc}"><xsl:value-of select="title" /></a><br /> </xsl:if> <xsl:if test='@type="form"'> <form method="{method}" action="{action}"> <xsl:for-each select="input"> <input class="search" type="{@type}" name="{@name}" size="10" value="Search" maxlength="{@maxlength}" /> </xsl:for-each> </form> </xsl:if> </xsl:for-each> </xsl:template> <xsl:template name="content"> <strong><xsl:value-of select="mySite/@page" /></strong> <br /> <xsl:for-each select="mySite/greeting/para"> <p> <xsl:value-of select="."/> </p> </xsl:for-each> <hr width="454" align="center" /> <span class="news">News::</span> <br /> <div class="news"> <xsl:for-each select="document('arg:/stories')/news-story"> <span class="newstime"><xsl:value-of select="date" /></span> <div class="newsitem"> <xsl:value-of select="story" /> </div> <br /> </xsl:for-each> </div> </xsl:template> </xsl:stylesheet>
You could repeat this and create many different XSL files to output many different pages (such as a WML page for viewing on a WAP enabled device). If you stored more dynamic content in another slot of the $xsltArg array, you can retrieve it in your XSL file by using:document('arg:/<name of slot>')
where <name of slot> would be the name of the slot in the array.

Now all that is left to do is apply the XSL transformation to the XML file. To do this, I use php's XSLT extension, Sablotron. I should mention that Sablotron is not enabled in default php installations. To activate it on a *nix machine, run the following:

./configure --enable-xslt --with-xslt-sablot 

If you're being hosted by someone else, ask them to do it for you. I chose a server side transformation because many browsers lack the ability to do transformations on the client end. By doing the transformation on the server, you're guaranteed that the transformation will occur.

The simplest way to use XSLT in php is to pass the path to both the XML file and the XSL file to the xslt_run() function like this:

// First create an XSLT processor. $xh= xslt_create(); // $xsl holds the path to the XSL file. $xml holds the path to the XML file. xslt_run($xh, $xsl, $xml, "arg:/_result", NULL, $xsltArgs); $result= xslt_fetch_result($xh); // Finally, free the XSLT processor since we're done using it. xslt_free($xh);

The $result variable will hold the transformed page which you can then output using echo or do whatever else you may want to do.
The transformation process is a bit different on servers running PHP 4.1 and above. I believe, for completeness, I should explain how it is done. If you're running a lower of version of php, feel free to skip this part. With the advent of PHP 4.1, a new interface to the XSLT engine has been added. Now, to transform an XML file, one does the following:// First create an XSLT processor. $xh = xslt_create(); // Next, pass either two variables, one holding the path to an XSL file and one // holding the path to an XML file. $result holds the transformed data. $result= xslt_process($xh, $xsl, $xml, NULL, $xsltArgs); // Finally, free the XSLT processor since we're done using it. xslt_free($xh);

0 comments:

Post a Comment

Dear Visitors All The Tricks And Hacks Posted Here Are Only For Knowledge Purpose.Don't Use These for Illegal Operations.

 
Twitter Bird Gadget