Spanish versions too!

27th June 2007

I am a little late in announcing this as my email inbox is overflowing and I missed the mail :(

Claudio Cossio has translated both my Zend Framework tutorial and my Zend Auth Tutorial into Spanish!

Thanks very much Claudio.

Would have made me laugh…

26th June 2007

.. if I didn't identify so much with it.

This was written in 2002, but is very relevant to my job today.

If Architects Had to Work Like Web Designers

Zend_Auth tutorial in French

6th June 2007

Just a quick heads up to let you know that the team at developpez.com have created a French version of my Zend_Auth tutorial. The French version of my tutorial, Débutez avec le Zend Framework, has also been updated in line with the 1.4.0. version.

Thanks guys!

Notes on using Oracle with my tutorial

6th June 2007

William Graham has been playing with the Zend Framework and Oracle using my tutorial.

His notes are very useful if you want to get my admittedly MySQL-centric tutorial working with Oracle. I've come across that uppercase field name thing before in an application I wrote at work that needed to transfer some data from Oracle to SQL Server. Took me a while to work out what was going on.

I'm a little confused about the case of form element names in $_POST, so will have to test that at some point.

Extending ViewRenderer to Support Layout Templates

2nd June 2007

Contrary to what my tutorial says, I'm one of those people that doesn't want to have to render my common header and footer templates in every single view script file. I prefer a standard site-wide layout script file that will display the content of the action script files within it.

The Zend_Controller_Action_Helper_ViewRenderer action helper is a great bit of code that automates rendering a view template based on which action has been called. This is very useful, but renders the action template, not my layout template. To solve this, I am experimenting with extending the Zend_Controller_Action_Helper_ViewRenderer and overriding it so that it know about my layout template. I also prefer to use the view suffix "tpl.php" for my view scripts, so I've made my class automatically set my preferred view suffix.

On to the code…

The master site template is called site.tpl.php and lives in the views/scripts/ directory. A simplistic breakdown of it looks like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8″ />
<title><?php echo $this->escape($this->pageTitle);?></title>
<link rel="stylesheet" href="<?php echo $this->baseUrl?>/css/site.css" 
  type="text/css" media="screen" />
</head>
<body>
    <div id="header">
        <?php echo $this->menu();  /* menu view helper */ ?>
    </div>
    <div id="content">
        <?php echo $this->render($this->actionScript); ?>
    </div>
    <div id="footer">
        Copyright 2007 Rob Allen
    </div>
</body>
</html>

$this->actionScript is the script associated with the current action which is automatically determined by Zend_Controller_Action_Helper_ViewRenderer, so in the case of the index action with the index controller, the action script is views/scripts/index/index.tpl.php.

As Zend_Controller_Action_Helper_ViewRenderer doesn't know about site.tpl.php and we want to render that instead, we extend like this:

<?php
class Controller_Action_Helper_ViewRenderer 
    extends Zend_Controller_Action_Helper_ViewRenderer
{
    /**
     * Name of layout script to render. Defaults to 'site.tpl.php'.
     *
     * @var string
     */
    protected $_layoutScript 'site.tpl.php';
    
    
    /**
     * Constructor
     *
     * Set the viewSuffix to "tpl.php" unless a viewSuffix option is 
     * provided in the $options parameter.
     * 
     * @param  Zend_View_Interface $view 
     * @param  array $options 
     * @return void
     */
    public function __construct(Zend_View_Interface $view null, 
                                array $options = array())
    {
        if (!isset($options['viewSuffix'])) {
            $options['viewSuffix'] = 'tpl.php';
        }
        parent::__construct($view$options);
    }
    
    /**
     * Set the layout script to be rendered.
     *
     * @param string $script
     */
    public function setLayoutScript($script)
    {
        $this->_layoutScript $script;
    }
    
    /**
     * Retreive the name of the layout script to be rendered.
     *
     * @return string
     */
    public function getLayoutScript()
    {
        return $this->_layoutScript;
    }
    
    /**
     * Render the action script and assign the the view for use
     * in the layout script. Render the layout script and append
     * to the Response's body.
     *
     * @param string $script
     * @param string $name
     */
    public function renderScript($script$name null)
    {
        $this->view->baseUrl $this->_request->getBaseUrl();
        if (null === $name) {
            $name $this->getResponseSegment();
        }
        
        // assign action script name to view.
        $this->view->actionScript $script;
        
        // render layout script and append to Response's body
        $layoutScript $this->getLayoutScript();        
        $layoutContent $this->view->render($layoutScript);
        $this->getResponse()->appendBody($layoutContent$name);
        
        $this->setNoRender();
    }
}

All we need to do now is modify our bootstrap so that the new ViewRenderer is used rather than the default one. I do this in index.php before the first instantiation of the front controller:

<?php
// Use our ViewRenderer action helper
$viewRenderer = new Controller_Action_Helper_ViewRenderer();
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);

That's all there is to it. My action scripts now just contain the HTML specific to the action and my layout template is automatically rendered with the action's HTML in the right place!

Obviously this is my first cut on this and so is fairly rough at the edges. Thoughts and improvements always welcome!

Tutorial 1.4.0

1st June 2007

Zend Framework 1.0.0. RC1 is out and with it a new action helper called ViewRenderer. This is a great action helper that handles the View integration with the Controller. As as result, the controller action functions are simpler and so I've updated my tutorial to reflect this.

It's not a big change though: just remove all calls to $this->render() and $this->initView() in the controller!