In Part 1, we are able to split the content into parts and apply decorators on them separately. This can be achieved by using the following classes. I guess the render method of each class pretty much sums up what they do so I will not explain further.

<?php

/**
 * @see Zend_Form_Decorator_Abstract
 */
require_once 'Zend/Form/Decorator/Abstract.php';

/**
 * This class will store the content into this instance during rendering. You
 * can retrieve the stored content using the complementing class
 * App_Form_Decorator_Retrieve. When adding several instances of this decorator,
 * you will have to alias it. The alias given will be used as the name option of
 * the App_Form_Decorator_Retrieve decorator.
 *
 * Accepts the following option:
 * - clear: whether to clear the passed in content by returning an empty content.
 *
 * Add the following line to the init() function of the Zend_Form-extended class
 * and use 'Store' to instantiate this decorator class.
 *
 * $this->addPrefixPath('App_Form_Decorator', 'App/Form/Decorator', Zend_Form::DECORATOR);
 *
 * @category   App
 * @package    App_Form_Decorator
 */
class App_Form_Decorator_Store extends Zend_Form_Decorator_Abstract
{
    /**
     * @access protected
     * @var boolean
     */
    protected $_clear = null;
    /**
     * @access protected
     * @var string
     */
    protected $_content = null;

    /**
     * Specifies whether to clear the passed in content after it is stored in
     * this instance.
     *
     * @param  boolean  $clear  True if to clear the passed in content.
     * @return  App_Form_Decorator_Store  For method chaining.
     * @throws  App_Form_Decorator_Exception  If parameter is not valid.
     */
    public function setClear($clear)
    {
        if (!is_bool($clear))
        {
            require_once 'App/Form/Decorator/Exception.php';
            throw new App_Form_Decorator_Exception('Clear option is not defined');
        }

        $this->_clear = $clear;

        return $this;
    }

    /**
     * Returns whether to clear the passed in content after it is stored in
     * this instance.
     *
     * @return  boolean  True if to clear the passed in content.
     * @throws  App_Form_Decorator_Exception  If 'clear' option is not valid.
     */
    public function getClear()
    {
        if (is_null($this->_clear))
        {
            if (!is_null($clear = $this->getOption('clear')))
            {
                $this->setClear($clear);
                $this->removeOption('clear');
            }
            else
                $this->setClear(true);
        }

        return $this->_clear;
    }

    /**
     * Clears content stored in this instance.
     *
     * @return  App_Form_Decorator_Store  For method chaining.
     */
    public function clearContent()
    {
        $this->_content = null;

        return $this;
    }

    /**
     * Returns content stored in this instance.
     *
     * @param  boolean  $clear  True if to clear stored content in this instance.
     * @return  string  Stored content.
     */
    public function getContent($clear = false)
    {
        $content = $this->_content;

        if (is_null($content))
            $content = '';
        elseif ($clear)
            $this->clearContent();

        return $content;
    }

    /**
     * Store the passed in content for retrieval.
     *
     * @param  string  $content  Passed in content to store.
     * @return  string  Depending on the clear option, it is either empty content or as is.
     */
    public function render($content)
    {
        // Store the passed in content to this instance.
        $this->_content = $content;

        // Clear or return content.
        return ($this->getClear()) ? '' : $content;
    }
}
<?php

/**
 * @see Zend_Form_Decorator_Abstract
 */
require_once 'Zend/Form/Decorator/Abstract.php';

/**
 * This class will retrieve the stored content from complementing class
 * App_Form_Decorator_Store. When adding several instances of this decorator,
 * you will have to alias it. The alias is purely used to ensure the instances
 * will not overwrite each other. To retrieve the stored content, you will need
 * to pass the alias used in instantiating the App_Form_Decorator_Store
 * decorator to the 'name' option.
 *
 * Accepts the following options:
 * - name: The alias used when creating the App_Form_Decorator_Store instance.
 * - remove: Boolean value determining whether to remove the stored content
 *           after retrieval.
 * - separator: string with which to separate passed in content and retrieved
 *              content.
 * - placement: whether to append, prepend or replace with the retrieved
 *              content.
 *
 * Add the following line to the init() function of the Zend_Form-extended class
 * and use 'Retrieve' to instantiate this decorator class.
 *
 * $this->addPrefixPath('App_Form_Decorator', 'App/Form/Decorator', Zend_Form::DECORATOR);
 *
 * @category   App
 * @package    App_Form_Decorator
 */
class App_Form_Decorator_Retrieve extends Zend_Form_Decorator_Abstract
{
    /**
     * @access protected
     * @var string
     */
    protected $_name = null;
    /**
     * @access protected
     * @var boolean
     */
    protected $_remove = null;

    /**
     * Returns stored content from the App_Form_Decorator_Store instance.
     *
     * @param  boolean  $clear  True if to clear stored content after retrieval.
     * @return  string  Stored content.
     * @throws  App_Form_Decorator_Exception  If wrong decorator instance is retrieved.
     */
    protected function _getContent($clear)
    {
        $store = $this->getElement()->getDecorator($this->getName());

        if (!$store instanceof App_Form_Decorator_Store)
        {
            require_once 'App/Form/Decorator/Exception.php';
            throw new App_Form_Decorator_Exception('"' . $this->getName() . '" is not a App_Form_Decorator_Store decorator');
        }

        return $store->getContent($clear);
    }

    /**
     * Specifies the name/alias of the element decorator to retrieve.
     *
     * @param  string  $name  Name/alias of the element decorator to retrieve.
     * @return  App_Form_Decorator_Retrieve  For method chaining.
     * @throws  App_Form_Decorator_Exception  If parameter is not valid.
     */
    public function setName($name)
    {
        if (!is_string($name))
        {
            require_once 'App/Form/Decorator/Exception.php';
            throw new App_Form_Decorator_Exception('Element decorator name is not defined');
        }

        if (is_numeric($name))
        {
            require_once 'App/Form/Decorator/Exception.php';
            throw new App_Form_Decorator_Exception('Element decorator name must be alphanumeric');
        }

        $this->_name = $name;

        return $this;
    }

    /**
     * Returns name/alias of the element decorator to retrieve.
     *
     * @return  string  Name/alias of the element decorator to retrieve.
     * @throws  App_Form_Decorator_Exception  If 'name' option is not valid.
     */
    public function getName()
    {
        if (is_null($this->_name))
        {
            if (is_null($name = $this->getOption('name')))
            {
                require_once 'App/Form/Decorator/Exception.php';
                throw new App_Form_Decorator_Exception('Element decorator name is not defined in the options');
            }

            $this->setName($name);
            $this->removeOption('name');
        }

        return $this->_name;
    }

    /**
     * Specifies whether to remove the stored content in
     * App_Form_Decorator_Store instance after retrieval.
     *
     * @param  boolean  $remove  True if remove the stored content after retrieval.
     * @return  App_Form_Decorator_Store  For method chaining.
     * @throws  App_Form_Decorator_Exception  If parameter is not valid.
     */
    public function setRemove($remove)
    {
        if (!is_bool($remove))
        {
            require_once 'App/Form/Decorator/Exception.php';
            throw new App_Form_Decorator_Exception('Remove option is not defined');
        }

        $this->_remove = $remove;

        return $this;
    }

    /**
     * Returns whether to remove the stored content in
     * App_Form_Decorator_Store instance after retrieval.
     *
     * @return  boolean  True if remove the stored content after retrieval.
     * @throws  App_Form_Decorator_Exception  If 'remove' option is not valid.
     */
    public function getRemove()
    {
        if (is_null($this->_remove))
        {
            if (!is_null($remove = $this->getOption('remove')))
            {
                $this->setRemove($remove);
                $this->removeOption('remove');
            }
            else
                $this->setRemove(true);
        }

        return $this->_remove;
    }

    /**
     * Retrieves the stored content.
     *
     * @param  string  $content  Passed in content.
     * @return  string  Rendered content.
     */
    public function render($content)
    {
        switch ($this->getPlacement())
        {
            case self::APPEND:
                return $content . $this->getSeparator() . $this->_getContent($this->getRemove());

            case self::PREPEND:
                return $this->_getContent($this->getRemove()) . $this->getSeparator() . $content;

            default:
                return $this->_getContent($this->getRemove());
        }
    }
}

And finally, the App_Form_Decorator_Exception class for completeness.

App/Form/Decorator. You need to add this folder to the include_path similar to what you did for Zend library. Remember to enable autoloading using the Zend_Loader class. Other information can be found in the class remarks.

If there is any optimization or bug, please feel free to point them out so that I can update my copy as well.

Oh… One more thing, you can also used the same concept to create decorator that does formatting, such as indentation, of the rendered content if you haven’t thought of that.