New PHP and XML/XSLT Template Engines implemented

The past weekend, Davey asked me in an IRC chat that he's put off by Smarty and would like to use Serendipity without it for his next blog design. Mostly because of loosing some overhead.

I'm basically split oppinion on this: Smarty Templating is a great way to ease things up and unify a templating language that looks better and is more accessible to newbies. So this is basically an advantage that I, as a programmer, am willing to take. But to any one who's got his looks on grandma's performance pennies might think otherwise, and might think that PHP itself already is a templating language. Which I can understand. :-)

Smarty luckily has a pretty, pretty easy API facing towards the User. Basically all that Smarty needs are the assign and display methods. There are some more convenience functions, but let's disregard those for a moment.

With that in Mind, I was able to create a PHP AND an XML-Templating Engine for Serendipity, which completely bypasses Smarty by still using the same outward-facing API.

All that is needed is a "Smarty Emulation Layer". This one fakes the $serendipity['smarty']-Object in a way that will preserve the same method calls for other template APIs.

For Serendipity, this ended up in a new "" file: SVN Repository.

This file gives you a new class that the Serendipity-Frontend needs to instanciate, and which should be used in your PHP TEmplates then. The existing Smarty-Object calls in the Serendipity-PHP-Code will still be called as usual. Just by putting the variables into the global namespace, you can later access them in the usual *.tpl files. Those can then execute any PHP Code you want. It's actually pretty much like a Smarty-compiled template, but easier readable. Such a file would then look like this.

And - yes, I DO think this looks a lot more uglier than the nice Smarty-Themes. But there's an advantage - several serendipity API calls (like the plugin API) no longer needs to be wrapped through Smarty calls, but can be executed instantly. And that's good. ;-)

The other engine I initially talked about is the XML output. The class you need for that is also existing in the new file, and is even simpler than the PHP output. All assign() method calls will simply echo their variable to the browser as raw XML.

This might not sound so terribly exciting at first, but the possibilies are quite interesting: Via (browser- or PHP-based) XSLT transformations you can turn your XML into any XHTML you'd like. Even a simple XSL-Stylesheet might help you out with it already. And it gets really cool if you use different XSL/XSLT files to transform the raw XML to the proper display depending on the User Agent (think mobile application, fat client application - all with the same data base).

So much for the concept - practically I never had that much of a time with XSLT. Which means this part of the code is more a "proof of concept" part. Anyone who'd like to have a stab at it, please do so and report me. Boris from the Forums already got together a small XSLT file which I'll try to understand and make available soon. One disadvantage of the current XML transformation is that you cannot use the PHP language constants or plugin API calls in XML. For that you'd need to make your template's file call the PHP functions and relay the output to the XML element output. That's not hard, actually, but it's some work you'll have to go through. ;)

On a completely related side post, thanks to a comment from Falk I got down and change the assign() calls in Serendipity to assign_by_ref() in cases where it makes sense. This will then pass template variables by reference instead by value, which boils down to this: It saves memory. The memory footprint of my playground installation dropped from 5 MB to 3.4MB. This might possibly introduce some problems, especially with plugins, so if any of those get obvious (like missing output, wrong output, PHP errors) please notice me about that.

The files were committed to SVN trunk, the 1.1 alpha nightlies. And even if this work is completely redundant: It only took an hour. *g*

Have fun experimenting!

(This post was originall written in german on my personal blog.)


Trackback-URL für diesen Eintrag


Ansicht der Kommentare: (Linear | Verschachtelt)

Matthew Weier O'Phinney am um :

I recently did a similar thing with Cgiapp2's use of templates by separating templates to a plugin layer and creating a template interface. To implement the interface, you simply implement three methods, init(), assign(), and fetch(). Those three methods pretty much define the API of any templating solution I've used, and I delivered Smarty, Savant2 and 3, and XSLT in the distribution.

If you add in an additional method for returning the actual engine instance, you then have access to modify it -- for instance, to register modifiers in Smarty, or filters and helpers in Savant.

The code is licensed under the BSD -- feel free to take a look at it and see if it may fit the needs of Serendipity; with it, you may be able to provide additional templating solutions to fit the needs of other developers.

judas_iscariote am um :

Garvin, Why reinventing the wheel ?

I think the vast mayority of your users don't care about a few miliseconds or a tiny amount of RAM, hardware is cheap after all.

Sorry, but I just don't get it.

Garvin am um :

Hi Judas!

Well, if you read the whole posting, you know why. :-))

A person requested it, I implemented it. It took no time, it is a perspective for PHP users. It does not hurt. It was fun. That's what OpenSource is about, right?

Best regards, Garvin

Garvin am um :

Hi Matthew!

Thanks a lot for telling me about this. I'll have a look at that and see if there is a common crossing to work on. Many thanks for sharing and best regards, Garvin.

Arnaud am um :

To the extent that you do not have too many people reading your blog and are not hosted on a shared host where resources used are important.

pacoit am um :

Has anyone considered phpTAL templating system? It's very nice, and editor-friedly (though I don't use graphical html editors).

Garvin am um :

I haven't checked that out yet, but from first glance it should really be easily implementable like the other engines. The assign() method would put the variable into member properties, and display() would map to execute()...

Memfis am um :

From my experience Smarty processing can easily take up to 30% of processing time for large pages. So any move from PHP code to external, highly optimized libraries is quite beneficial.

Judebert am um :

Brilliant, Garvin! My RL job involves a lot of this kind of adaptation. It's exactly what I would have done.

Kommentar schreiben

Die angegebene E-Mail-Adresse wird nicht dargestellt, sondern nur für eventuelle Benachrichtigungen verwendet.

Um maschinelle und automatische Übertragung von Spamkommentaren zu verhindern, bitte die Zeichenfolge im dargestellten Bild in der Eingabemaske eintragen. Nur wenn die Zeichenfolge richtig eingegeben wurde, kann der Kommentar angenommen werden. Bitte beachten Sie, dass Ihr Browser Cookies unterstützen muss, um dieses Verfahren anzuwenden.

BBCode-Formatierung erlaubt
Markdown-Formatierung erlaubt