Zend_Form is a great component to help with the headache of form creation, validation and error handling. I’ll be the first to admit that I’ve had problems with the configuration of the Decorators, however one of the more powerful ones; ViewScript is somewhat overlooked. This decorator, to me seems to be the most logical way to configure how form elements and error messages are rendered, it also removes the need for the smelly practice of defining bits of html in your application code. Here’s the example, lifted straight from the documentation

Firstly we tell the Zend_Form_Element object to use the ViewScript decorator.

<?php

// Setting the decorator for the element to a single, ViewScript,
// decorator, specifying the viewScript as an option, and some extra
// options:
$element->setDecorators(array(array('ViewScript', array(
	'viewScript' => '_element.phtml',
	'class'      => 'form element'
))));

// OR specifying the viewScript as an element attribute:
$element->viewScript = '_element.phtml';
$element->setDecorators(array(array('ViewScript', array('class' => 'form element'))));

And here’s code for _element.phtml

<div class="<?php echo $this->class ?>">

    <?php echo $this->formLabel($this->element->getName(), $this->element->getLabel()) ?>

    <?php echo $this->{$this->element->helper}($this->element->getName(), $this->element->getValue(), $this->element->getAttribs()) ?>

    <?php echo $this->formErrors($this->element->getMessages()) ?>

    <div class="hint"><?php echo $this->element->getDescription() ?></div>

</div>

As you can see, this approach gives you full access the element and the markup for rendering. If I had my way this would be the only approach, it’s more verbose and I’d even be comfortable letting my designers loose on it. However the example doesn’t go much further than this, so during development I encountered a few issues using different types of elements.

All that needs to be done specify the particular script for the element to render when declaring the ViewScript decorator, like this example of a Zend_Form_Element_Text element:

$element->setDecorators(
    array(array('ViewScript', array('viewScript' => 'input.phtml')))
);

Here’s some of scripts I’ve created along the way.

Text Input/Textarea (input.phtml)

I’ve added a little logic to check for errors in the element and add css class accordingly. This is not entirely neccessary but I think it highlights the ways you can use the ViewScript Decorators’ power.

<div class="element<?php if($this->element->hasErrors()): ?> errors<?php endif; ?>">

    <?= $this->formLabel($this->element->getName(), $this->element->getLabel()) ?>

    <?= $this->{$this->element->helper}($this->element->getName(), $this->element->getValue(), $this->element->getAttribs()) ?>

    <?php if( $this->element->hasErrors() ): ?>

        <div class="messages">

            <?= $this->formErrors($this->element->getMessages()) ?>

        </div>

    <?php endif; ?>

</div>

Select (select.phtml)

There’s only one difference here and it’s the results of the call to getMultioptions() on the element being passed to the element view helper.

<div class="element<?php if($this->element->hasErrors()): ?> errors<?php endif; ?>">

    <?= $this->formLabel($this->element->getName(), $this->element->getLabel()) ?>

    <?= $this->{$this->element->helper}($this->element->getName(), $this->element->getValue(), $this->element->getAttribs(), $this->element->getMultiOptions()) ?>

    <?php if( $this->element->hasErrors() ): ?>

        <div class="messages">

            <?= $this->formErrors($this->element->getMessages()) ?>

        </div>

    <?php endif; ?>

</div>

Submit (submit.phtml)

<div class="element">

    <?= $this->{$this->element->helper}($this->element->getName(), $this->element->getValue(), $this->element->getAttribs()) ?>

</div>

So there you have it. A simple solution to the complex issue of Zend_Form_Element Decorators.