Extending Zend_View_Interface for use with Smarty

Zend Framwork v0.6 has introduced new MVC code and one of the changes is that Zend_View_Interface now exists to allow for easy implementation of other templating engines other than PHP based ones like Zend_View or Savant.

We use Smarty at work and when we migrate our content management framework to Zend Framework, we intend to continue using Smarty. Hence, I've created AkCom_View_Smarty to play with how we are going to use Smarty within the Zend Framework. I think that part of the release also has an implemention of Zend_View_Interface that uses Smarty, so it's worth looking at that solution too!

My code is really simple:


/**
 * Concrete class for handling Smarty view scripts.
 *
 * @category   AkCom
 * @package    AkCom_View
 * @copyright  Copyright (c) 2006 Rob Allen (http://www.akrabat.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class AkCom_View_Smarty implements Zend_View_Interface
{
    /**
     * @var Smarty
     */
    protected $_engine;

    function __construct($params null)
    {
        $this->_engine = new Smarty();
        
        // force error_reporting and hope smarty can cope with E_STRICT!
        $this->_engine->error_reporting E_ALL|E_STRICT;
        
        // I like {{ and }} for delimiters!
        $this->_engine->left_delimiter '{{';
        $this->_engine->right_delimiter '}}';
        
        // Render variables XSS safe by default.
        $this->_engine->default_modifiers = array('escape:"htmlall"');

        // AkCom specific: include our default plugins
        $this->_engine->plugins_dir[] = dirname(__FILE__) . '/plugins.';

        // pass any param passed to the constructor to Smarty
        if (is_array($params)) {
            foreach ($params as $key=>$value) {
                $this->_engine->$key $value;
            }
        }
    }

    public function getEngine()
    {
        return $this->_engine;
    }

    public function setScriptPath($path)
    {
        $this->_engine->template_dir $path;
    }

    public function __set($key$val)
    {
        $this->_engine->assign($key$val);
    }

    public function __get($key)
    {
        return $this->_engine->get_template_vars($key);
    }

    public function __isset($key)
    {
        $var $this->_engine->get_template_vars($key);
        return !is_null($var); 
    }

    public function __unset($key)
    {
        $this->_engine->clear_assign($key);
    }

    public function assign($spec$value null)
    {
        $this->_engine->assign($spec$value);
    }

    public function clearVars()
    {
        $this->_engine->clear_all_assign();
    }

    public function render($name)
    {
        return $this->_engine->fetch($name);
    }

    public function setPluginsPath($dir)
    {
        $this->_engine->plugins_dir $dir;
    }

    public function addPluginsDir($dir)
    {
        $this->_engine->plugins_dir[] = $dir;
    }

    public function setCompilePath($dir)
    {
        $this->_engine->compile_dir $dir;
    }
    
    public function setCachePath($dir)
    {
        $this->_engine->cache_dir $dir;
    }
    
    public function setCacheLifetime($seconds)
    {
        $this->_engine->cache_lifetime $seconds;
    }
}

As you can see, most of the code is in the constructor so that I can set up the instance of Smarty in the way that I like and then I've implemented assign() so that it works the same as Zend_View_Abstract for consistency's sake. I've also implemented a few helper functions that are Smarty specific to make setting the common properties that need setting easier.

One thing I like about this code is that it shows that it's quite simple to create a concrete class from Zend_View_Interface and so using the template engine of your choice isn't actually that hard!

If you would like to comment on this article, please ping me on twitter.
If your response won't fit into 140 characters, write a blog post and then ping me!