Proposal for "Template_Savant"

» Metadata » Status
  • Category: HTML
  • Proposer: Paul Jones 
  • License: LGPL
» Description

HTML_Template_Savant

Overview

Savant is a powerful but lightweight template system for PHP. It is primarily for PHP developers, not HTML designers, although anyone with any amount of PHP knowledge can use it.

Savant uses PHP itself as its template language so you don't need to learn a new markup system (c.f. comments and explanation from Harry Fuecks and Brian Lozier). Savant leverages the existing strengths of PHP to create the most effective template system possible.

Savant is not Xipe-lite, becuase Savant is not a compiling template engine. All compiling template engines have an inherent security risk of requiring a writable directory, as well as making re-distributable templates very difficult to maintain. Savant does not carry this risk or diffuculty.

Unlike other non-compiling template engines, Savant has no need for complex template parsing logic, and is therefore lightweight, faster than any existing template engine, and has the capability to generate binary files as well as text files. Savant could be used to generate customized images, for instance. No HTML_Template_* engine has this kind of power. In fact, a better top-level category for Savant would be just "Template" (for "Template_Savant").

Savant has an object-oriented system of template plugins and output filters, so it sports almost all of the power and flexibility of Smarty with almost none of the overhead.

Provides

Savant...

  • assigns variable copies (scalar, array, or object) and variable references for parsing through to a PHP-based template script via the methods assign() and assignRef() (there is an assignObject() method specifically for assigning object references)
  • includes then displays or returns the template script output via the display() and fetch() methods
  • provides an object-oriented system of plugins that add "convenience functions" for your display logic using plugin() and splugin() methods
  • provides an object-oriented system of output filters to automatically process the parsed output of the template script via the setFilter() and mapFilter() functions.
  • provides a simple path management system through addPath(), getPath(), and findTemplate() that allows you mix and match locations for plugins, filters, and templates, making it a great foundation for distrbuted and/or theme-aware applications.
  • has full documentation at http://phpsavant.com/ with examples and user comments.

Savant does not compile templates. Savant templates are written in plain, natural PHP with regular <?php ... ?> tags, so no compilation or evaluation is necessary; it just includes the template code within the Savant object context at display() or fetch() time.

Savant does not have a built-in caching mechanism. If you want to cache output, I figure you probably want your application to provide that, not the template subsystem. Use Cache or Cache_Lite if you want to cache Savant output.

Example

Logic Script

Here is an example use of Savant. The following business logic script populates and displays a Savant template (shown below).


<?php


// load the Savant class file
require_once 'Savant.php';

// generate an array of book authors and titles
$booklist = array(
    array(
        'author' => 'Stephen King',
        'title' => 'The Stand'
    ),
    array(
        'author' => 'Neal Stephenson',
        'title' => 'Cryptonomicon'
    ),
    array(
        'author' => 'Milton Friedman',
        'title' => 'Free to Choose'
    )
);

// generate a list of some other variables
$varlist = array(
    'var1' => 'some value',
    'var2' => 'some other value',
    'var3' => 'yet another value'
);

// create a title for the page
$title = "My Page Title";

// create a Savant object
$savant =& new Savant();

// assign values to the template variables
$savant->assign('book', $booklist);
$savant->assign('title', $title);
$savant->assign($varlist);

// display the template with the assigned values
$savant->display('example.tpl.php');

?>

In the above example, we use an array to assign a number of template variable tokens at once; it is just as easy to assign an object instead of an array, and the object properties will be assigned to the template.

Template Script

Here is the Savant template script, called example.tpl.php. Note how we use the alternative syntax for control structures here; it's not required, but it can be easier to read in many cases.

<html>

    <head>
        <title><?php echo $title ?></title>
    </head>

    <body>
        
        <p>These variables were set as an array where the array key 
        was the variable name and the array value was the variable 
        value.</p>
        
        <ul>
            <li><?php echo $var1 ?></li>
            <li><?php echo $var2 ?></li>
            <li><?php echo $var3 ?></li>
        </ul>
        
        <?php if (is_array($book)): ?>
            
            <table>
                <tr>
                    <th>Author</th>
                    <th>Title</th>
                </tr>
                
                <?php foreach ($book as $key => $val): ?>
                    <tr>
                        <td><?php echo $val['author'] ?></td>
                        <td><?php echo $val['title'] ?></td>
                    </tr>
                <?php endforeach; ?>
                
            </table>
            
        <?php else: ?>
            
            <p>There are no books to display.</p>
            
        <?php endif; ?>
        
    </body>
</html>

Note that the template language is natural PHP without any special markup or "helpful" shortcuts.

Because the template is in natural PHP, any errors in processing the template are immediately transparent, as they are reported on the actual source template script and not an intermediary cached or compiled script.

Plugins and Filters

You can use the standard Savant plugins within your Savant template, and you can write your own. Savant plugins are comparable to Smarty plugins. Please see http://phpsavant.com/index.php?page=SavantPlugins for more information.

You can use the standard Savant output filters on the displayed or fetched template output, and you can write your own. Please see http://phpsavant.com/index.php?page=SavantFilters for more information.

Caching

Here is a simple example of how to cache output with Savant and Cache_Lite.


<?php

// assume existence of Cache_Lite object called $cache
// and a unique page ID called $id.  hit the cache.
$output = $cache->get($id);

// was there cached output?
if (! $output) {
    // no, generate and save it
    $savant =& new Savant();
    $savant->assign(...); // whatever
    $output = $savant->fetch('template.tpl.php');
    $cache->save($output, $id);
}

echo $output;
?>

Other Packages

Why does PEAR need another template system? Why not contribute to another package?

All of the PEAR template packages do some form of template compiling and evaluation, and they all (with one exception, sort of) use a custom template language. Savant does neither: no compiling, and no special markup.

IT, PHPLIB, Sigma

These template engines are not directly comparable to Savant for various reasons.

  • IT -- Evaluates templates with regular expressions. A holdover from PHP3 and early PHP4 days.
  • PHPLIB -- Evaluates templates with regular expressions. A holdover from an earlier framework system.
  • Sigma -- Evaluates templates with regular expressions, and optionally caches the evaluated template code.

Flexy, Xipe

These template engines are comparable to Savant because of the power and flexibility they provide.

  • Flexy -- Compiles to PHP from custom markup. No comparable plugin or output filter system.
  • Xipe -- Compiles to PHP from custom markup. No comparable plugin or output filter system.

Again, Savant is already in PHP, so no compilation is necessary. Although Xipe supports pre- and post-filters, they apply to the compiled PHP code, not the generated output.

Of these template systems in PEAR, the one that is brought up most often form comparison is Xipe. This came up on the Savant website; the question is verbatim, but I have updated and edited the answer for use in this proposal (it is substantially the same answer as on the website).

Question:

Could you please outline the major differences of Savant compared to
HTML_Template_Xipe? To me it seems these two projects have the same goals
but Xipe is easier to use (no need for <?php ... ?> and automatic echoing
of values). I am referring to Xipe using the SimpleTag language here.What does Savant offer over Xipe?

My answer:

Among other things, Xipe compiles its templates, and Savant does not.

Even though Xipe uses PHP as its language, it still compiles the
templates, which adds to time and overhead on the first processing pass
(and perhaps subsequent passes). Savant uses plain PHP and does not need
to compile.

Xipe uses variables directly from the script, without a step for
"assigning" them to the template; Savant uses an explicit "assign()"
method to push variables to the template.

...

The documentation for Xipe is not complete, although it does come in three
flavors (.html, .sxw, and .pdf); Savant docs are complete and online with
comments enabled. :-)

Xipe does not appear to have a plugin system like Savant, although it does
have a similar filter system (but there's no documentation on how to write
your own filters). ...

Xipe tries to add new template language elements (the SimpleTag language),
tries to interpret indents, and so on. Yes, you can "turn off" those
features but you have to know about them to do that. Savant uses PHP, all
of PHP, and nothing but PHP, in normal PHP format (ugly long tags and
everything ;-).

In short, the "simplicity" of Xipe takes some time to learn and get used
to; Savant is just PHP right out of the box.

None of this is to say that Xipe is bad; it is certain that it appeals to
many developers (e.g., its translation routines look quite nice).

Other Reasons For Savant

Savant templates are easy for new and experienced PHP developers to comprehend, modify, and debug, becuase templates are already in PHP (no need to learn a new template markup)

Savant templates, because they are already in PHP, can be documented with phpDocumentor.

Savant templates can be used for anything: HTML, RSS, XML, PDF, RTF, any kind of binary or text file.

Savant does not attempt to impose on your coding style any more than minimally necessary, and at the same time it tries to operate as intelligently and transparently as possible. For example, if you like assigning individual scalar elements, assign() works for you; if you prefer to assign by associative array, assign() works for you too; finally, if object properties are your thing, assign() still works for you.

Savant is perfect for distributed applications. Among other things, the end user does not have to worry about compile-directory or cache-directory permissions, because Savant does not compile templates. Because of the path management utilities in Savant, developers can make their applications theme-aware with little effort.

Savant is STABLE at version 1.5 and in production at many high-traffic sites, although the package file linked in this proposal is 0.0.x-devel due to refactoring based on proposal commentary.

Harry Fuecks notes:

...it's "low risk" for users - there's minimal lock in to the template syntax - if someone decides to ditch Savant at a later date, the templates can, more or less, still be used.

And finally, in reference to a recent PEAR-QA thread, it appears that Wolfram Kriesing is orphaning Xipe. Because Flexy is the natural successor of Xipe, Xipe may eventually be deprecated.

Possible Enhancements

  • Add I18N plugins or filters
  • When PHP5 is widely available, use __call() overloading to call plugins instead of $this->plugin()
» Dependencies » Links
» Timeline » Changelog
  • First Draft: 2004-05-31
  • Proposal: 2004-06-01
  • Call for Votes: 2004-06-08
  • Paul Jones
    [2004-06-01 18:46 UTC]

    Removed reference to Xipe "cache" in the final section; Xipe optionally caches the compiled script, not the output.

  • Paul Jones
    [2004-06-04 03:05 UTC]

    Mostly finished with refactoring, streamlined plugin and filter loading, updated comments, updated plugins and filters to new naming conventions, created development package, changed proposal links.

  • Paul Jones
    [2004-06-07 00:03 UTC]

    Added note about PEAR-QA thread regarding Xipe.

    "And finally, in reference to a recent PEAR-QA thread, it appears that Wolfram Kriesing is orphaning Xipe. Because Flexy is the natural successor of Xipe, Xipe may eventually be deprecated."