PHP + Smarty + XML = SmartyPath?
I use PHP almost exclusively for all my web stuff. Because I am a firm believer of separation of concerns I also use a template engine with PHP called Smarty, the Compiling Template Engine. My website has content coming from several places (database, html files, jabber) and it would be nice to have some common data format: XML.
XML has been getting a lot of attention by me lately, mostly because of my interest in Jabber. A few weeks ago I got Perl & XML, a great O'Reilly book. Among all useful stuff about, you guessed it, Perl and XML, there was a reference to AxKit. AxKit is a Perl based XML Application Server for Apache and one of it's features is a XML stylesheet language called XPathScript which combines aspects of XSLT with the scriptability of Perl. Really cool stuff!
So what do we have? I use PHP now, but the ideas of AxKit are really appealing. What to do? What most people in this business do: hack up something which scratches that itch. Enter SmartyPath. In Smarty it is really easy to make new template functions, modifiers, filters and other stuff, so I put together some Compiler Functions to use Smarty templates for translating XML documents, similar to XSLT, in a procedural as well as a declarative manner. It still needs a lot of work, I think, but pretty much works already. Here is an example:
<webpage>
<head>
<title>Who is ralphm?</title>
</head>
<body>
<section>
<title>Who is ralphm?</title>
<p>That would be me. <em>Ralph Meijer</em> .... </p>
<subsection>
<title>Pictures?</title>
<p><img src="/images/ralphm1.jpg"/><img src="/images/ralphm2.jpg"/></p>
</subsection>
</section>
</body>
</webpage>
{template match="section"}{apply_templates}{/template}
{template match="subsection"}{apply_templates}{/template}
{template match="p"}{element}{apply_templates}{/element}{/template}
{template match="img"}{empty_element}{/template}
{template match="em"}<b>{apply_templates}</b>{/template}
{template match="title"}
{if ($node->findvalue("name(..) = 'section'"))}
<h1>{apply_templates}</h1>
{else}
<h2>{apply_templates}</h2>
{/if}
{/template}
<html>
<head>
<title>{findvalue xpath="/webpage/head/title/text()"}</title>
</head>
<body>
{apply_templates match='/webpage/body/*'}
</body>
</html>
I'll hack on it some more and make it available for download later on. Drop me a note if you are interested in this little project.