ayTemplates - Optimized template engine

Submitted by davidc on Sat, 21/09/2002 - 00:51

ayTemplates is a PHP extension written in C, designed for lightning-fast execution of standard template operations. At 99dogs, we were using a derivative of FastTemplate for some very heavy templating, as we had a team of web designers working independently from the programmers. Doing all this in PHP with regular expressions was insanely slow and inappropriate, so ayTemplates was born.

There never was a public release of ayTemplates, despite being written in 2002 and being improved through 2004. Around that time 99dogs finally gave up the ghost, and I stopped writing PHP professionally, so it never saw production. I occasionally still get enquiries about it though, so here in 2009, I'm finally releasing it. The documentation below is sparse and possibly out of sync with the code.

License

PHP license, see LICENSE in PHP distribution. Copyright is held by David Croft.

Usage

string tpl_parse(string template, array vars [, mixed callback_function])

string template
template string (containing {variables}) to parse
array vars
array of variables definitions to parse into the template. Array key is the variable name, array value is the value to use. (If you only want to use the callback functionality, pass in an empty array).
mixed callback_function
Callback function (string), or callback class/instance method (array). See below for more details.
object callback_object
Object on which to perform the callback (in which case callback_function is treated as a method of that object).

Callback functions

The default behaviour when ayT finds a template variable that it cannot parse is to throw an error and abort the current parse. To override this behaviour, you can define a callback function for ayT to use. The prototype of the callback function should be:

mixed callback_function(string var, boolean squelching)

The function is passed a string containing the full text of the unrecognized template variable, and a boolean to indicate whether squelching is in effect (more on this later).

The return value should be the string to substitute into the template. Alternatively the following values are permitted:

  • TPL_ABORT - the call to tpl_parse() will exit, returning null. No error or warning will be printed, so you must do so yourself.
  • TPL_SQUELCH - squelching is turned on. No further text will be copied to the template output, neither literal text nor array variables. However the callback function will continue to be called (with the squelching parameter set to true) - any string returned by the function will be copied to the output.
  • TPL_UNSQUELCH - squelching is turned off again.

A possible use of this callback function is to silently ignore the error (if appropriate for your application), or to report it in a friendly manner, or other application-specific logic. For example:

function callback_handler($var, $sq) { return '[Unable to parse section '.$var.']'; }

A more innovative usage is demonstrated in the supplied ayTemplateParser class. On this object you can register various 'handlers' that accept different types of template variable. For example, the 'banner' handler would be called for every template variable of the form '{banner:768x60:commerce}'. This is accomplished by (a) the handlers registering with the ayTemplateParser method registerHandler and (b) the callback function decoding unrecognized template variables to determine whether a handler should be utilized.

Squelching

While squelching is turned on, neither literal text in the template nor template variables found in the array will be copied to the output. However, the callback function will continue to be called for unrecognised variables (with its squelching parameter set to true).

The callback function can return text if you wish, and such text will be copied to the output, but you more than likely want to just return the empty string to avoid adding anything.

What on earth is the point of squelching then ? Well, it enables such fun stuff as this:

{if:page < pages} Next page {endif}

This enables you to develop conditional processing under the control of your callback function. The supplied example TemplateParser class does this.

Clearly one needs to be able to unsquelch when {endif} is reached, so the callback handler must continue to be called, but in the meantime you don't want any output to be produced, so your callback might look something like this:

function callback_handler($text, $squelching) { if (text is a control statement) { // process control statement, possibly returning TPL_SQUELCH or TPL_UNSQUELCH // if you're implementing this yourself, remember that if statements might be nested } else if ($squelching) { return ""; } else { // process normal statement } } TODO supplied callback handlers: if/else/endif raw htmlentities

Installation Instructions

There are two ways to install ayT - as a built-in extension to PHP, or a dynamic extension. The dynamic extension can be used in two ways - always loaded, or dynamically loaded.

Installing as a built-in extension to PHP will give you the best performance. However you will need to have root privileges and the latest version of autoconf to recompile PHP.

Compiling as a dynamic extension will produce a shared library file that can be dynamically linked to PHP at runtime. You can then either load the extension permanently via php.ini, where it will load when PHP starts up, or you can load it yourself using the dl() function. dl() is deprecated as of PHP 5.0 and the php.ini is far more efficient anyway, avoiding the dynamic linking on every pageview.

Compilation as a built-in extension

Note: this method requires autoconf version 1.4

  1. Copy the 'tpl' directory into the ext/ subdirectory of the PHP source
  2. From the PHP root dir, do ./buildconf
  3. ./configure as usual, with the extra flag --enable-tpl
  4. make
  5. make install

Compilation as a dynamic extension

  1. Run phpize from this dir, e.g. /[php install dir]/phpize
  2. ./configure --enable-tpl
  3. make
  4. make install
  5. Either:
    1. add directive to your php.ini to load this module, or
    2. call dl('tpl.so') as required (inefficient)

php.ini directives

If you have compiled ayTemplates as a dynamic extension, and wish to have it loaded automatically, add the following line:

extension=tpl.so

You may need to check that your extension_dir directive is also valid.

ayTemplates has no configuration directives at this time.

Changelog

27/08/2002 Version 0.03 download

  • First public release

(Unreleased) Version 0.04

  • Third parameter can now be array($object, $methodname) to call an instance method. Fourth parameter (which was an optional object) is no longer supported.
  • tpl_go() now returns null on error, not false.
  • The callback can now return TPL_ABORT to abort, or TPL_SQUELCH/TPL_UNSQUELCH to prohibit copying literal text or array variables until unsquelched.
  • The callback is now passed a second parameter, bool squelching. The callback is called and anything it returns is appended regardless of whether squelching is on, so you should check this param and return nothing if squelching (unless it's a control construct that might turn squelching back off!)
  • Callback can no longer return random types, it must return the substitution string, or a TPL_ define

The following changes break compatibility that the previous version introducted to avoid messing up Javascript. Instead, it is now recommended that you add a 'raw' callback option, so for example you could use the following in your template: