<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.form.standardDecorators">
    <title>Standard Form Decorators Shipped With Zend Framework</title>

    <para>
        <classname>Zend_Form</classname> ships with several standard decorators. For more
        information on general decorator usage, see <link
            linkend="zend.form.decorators">the Decorators section</link>.
    </para>

    <sect2 id="zend.form.standardDecorators.callback">
        <title>Zend_Form_Decorator_Callback</title>

        <para>
            The Callback decorator can execute an arbitrary callback to
            render content. Callbacks should be specified via the 'callback'
            option passed in the decorator configuration, and can be any
            valid <acronym>PHP</acronym> callback type. Callbacks should accept three
            arguments, <varname>$content</varname> (the original content passed to
            the decorator), <varname>$element</varname> (the item being
            decorated), and an array of <varname>$options</varname>. As an example
            callback:
        </para>

        <programlisting language="php"><![CDATA[
class Util
{
    public static function label($content, $element, array $options)
    {
        return '<span class="label">' . $element->getLabel() . "</span>";
    }
}
]]></programlisting>

        <para>
            This callback would be specified as <methodname>array('Util',
                'label')</methodname>, and would generate some (bad) <acronym>HTML</acronym> markup
            for the label. The Callback decorator would then either replace,
            append, or prepend the original content with the return value of
            this.
        </para>

        <para>
            The Callback decorator allows specifying a <constant>NULL</constant> value for the
            placement option, which will replace the original content with
            the callback return value; 'prepend' and 'append' are still
            valid as well.
        </para>
    </sect2>

    <sect2 id="zend.form.standardDecorators.captcha">
        <title>Zend_Form_Decorator_Captcha</title>

        <para>
            The Captcha decorator is for use with the <link
                linkend="zend.form.standardElements.captcha">CAPTCHA form
                element</link>. It utilizes the CAPTCHA adapter's
            <methodname>render()</methodname> method to generate the output.
        </para>

        <para>
            A variant on the Captcha decorator, 'Captcha_Word', is also commonly
            used, and creates two elements, an id and input. The id indicates
            the session identifier to compare against, and the input is for the
            user verification of the CAPTCHA. These are validated as a single
            element.
        </para>
    </sect2>

    <sect2 id="zend.form.standardDecorators.description">
        <title>Zend_Form_Decorator_Description</title>

        <para>
            The Description decorator can be used to display a description set
            on a <classname>Zend_Form</classname>, <classname>Zend_Form_Element</classname>, or
            <classname>Zend_Form_DisplayGroup</classname> item; it pulls the description
            using the object's <methodname>getDescription()</methodname> method. Common use
            cases are for providing UI hints for your elements.
        </para>

        <para>
            By default, if no description is present, no output is generated. If
            the description is present, then it is wrapped in an <acronym>HTML</acronym>
            <emphasis>p</emphasis> tag by default, though you may specify a tag by
            passing a <property>tag</property> option when creating the decorator, or
            calling <methodname>setTag()</methodname>. You may additionally specify a class
            for the tag using the <property>class</property> option or by calling
            <methodname>setOption('class', 'foo')</methodname>; by default, the class 'hint' is used.
        </para>

        <para>
            The description is escaped using the view object's escaping
            mechanisms by default. You can disable this by passing a
            <constant>FALSE</constant> value to the decorator's 'escape' option or
            <methodname>setEscape()</methodname> method.
        </para>
    </sect2>

    <sect2 id="zend.form.standardDecorators.dtDdWrapper">
        <title>Zend_Form_Decorator_DtDdWrapper</title>

        <para>
            The default decorators utilize definition lists
            (<emphasis>&lt;dl&gt;</emphasis>) to render form elements. Since form
            items can appear in any order, display groups and sub forms can
            be interspersed with other form items. To keep these particular
            item types within the definition list, the DtDdWrapper creates a
            new, empty definition term (<emphasis>&lt;dt&gt;</emphasis>) and wraps
            its content in a new definition datum (<emphasis>&lt;dd&gt;</emphasis>).
            The output looks something like this:
        </para>

        <programlisting language="html"><![CDATA[
<dt></dt>
<dd><fieldset id="subform">
    <legend>User Information</legend>
    ...
</fieldset></dd>
]]></programlisting>

        <para>
            This decorator replaces the content provided to it by wrapping
            it within the <emphasis>&lt;dd&gt;</emphasis> element.
        </para>
    </sect2>

    <sect2 id="zend.form.standardDecorators.errors">
        <title>Zend_Form_Decorator_Errors</title>

        <para>
            Element errors get their own decorator with the Errors
            decorator. This decorator proxies to the FormErrors view helper,
            which renders error messages in an unordered list
            (<emphasis>&lt;ul&gt;</emphasis>) as list items. The
            <emphasis>&lt;ul&gt;</emphasis> element receives a class of "errors".
        </para>

        <para>
            The Errors decorator can either prepend or append the content
            provided to it.
        </para>
    </sect2>

    <sect2 id="zend.form.standardDecorators.fieldset">
        <title>Zend_Form_Decorator_Fieldset</title>

        <para>
            Display groups and sub forms render their content within
            fieldsets by default. The Fieldset decorator checks for either a
            'legend' option or a <methodname>getLegend()</methodname> method in the
            registered element, and uses that as a legend if non-empty. Any
            content passed in is wrapped in the <acronym>HTML</acronym> fieldset, replacing the
            original content. Any attributes set in the decorated item are
            passed to the fieldset as <acronym>HTML</acronym> attributes.
        </para>
    </sect2>

    <sect2 id="zend.form.standardDecorators.file">
        <title>Zend_Form_Decorator_File</title>

        <para>
            File Elements have special notation when you use multiple
            file elements or subforms. The File decorator is used by
            <classname>Zend_Form_Element_File</classname> and allows to set multiple
            file elements with only a single methodcall. It is used
            automatically and fixes the elements name.
        </para>
    </sect2>

    <sect2 id="zend.form.standardDecorators.form">
        <title>Zend_Form_Decorator_Form</title>

        <para>
            <classname>Zend_Form</classname> objects typically need to render an
            <acronym>HTML</acronym> form tag. The Form decorator proxies to the Form view helper. It
            wraps any provided content in an <acronym>HTML</acronym> form element, using the
            <classname>Zend_Form</classname> object's action and method, and any
            attributes as <acronym>HTML</acronym> attributes.
        </para>
    </sect2>

    <sect2 id="zend.form.standardDecorators.formElements">
        <title>Zend_Form_Decorator_FormElements</title>

        <para>
            Forms, display groups, and sub forms are collections of
            elements. In order to render these elements, they utilize the
            FormElements decorator, which iterates through all items,
            calling <methodname>render()</methodname> on each and joining them with the
            registered separator. It can either append or prepend content
            passed to it.
        </para>
    </sect2>

    <sect2 id="zend.form.standardDecorators.formErrors">
        <title>Zend_Form_Decorator_FormErrors</title>

        <para>
            Some developers and designers prefer to group all error messages at
            the top of the form. The FormErrors decorator allows you to do this.
        </para>

        <para>
            By default, the generated list of errors has the following markup:
        </para>

        <programlisting language="html"><![CDATA[
<ul class="form-errors>
    <li><b>[element label or name]</b><ul>
            <li>[error message]</li>
            <li>[error message]</li>
        </ul>
    </li>
    <li><ul>
        <li><b>[subform element label or name</b><ul>
                <li>[error message]</li>
                <li>[error message]</li>
            </ul>
        </li>
    </ul></li>
</ul>
]]></programlisting>

        <para>
            You can pass in a variety of options to configure the generated
            output:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <property>ignoreSubForms</property>: whether or not to disable recursion into
                    subforms. Default value: <constant>FALSE</constant> (i.e., allow recursion).
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>markupElementLabelEnd</property>: Markup to append to element
                    labels. Default value: '&lt;/b&gt;'
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>markupElementLabelStart</property>: Markup to prepend to
                    element labels. Default value: '&lt;b&gt;'
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>markupListEnd</property>: Markup to append error message lists
                    with. Default value: '&lt;/ul&gt;'.
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>markupListItemEnd</property>: Markup to append individual
                    error messages with. Default value: '&lt;/li&gt;'
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>markupListItemStart</property>: Markup to prepend individual
                    error messages with. Default value: '&lt;li&gt;'
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>markupListStart</property>: Markup to append error message
                    lists with. Default value: '&lt;ul class="form-errors"&gt;'
                </para>
            </listitem>
        </itemizedlist>

        <para>
            The FormErrors decorator can either prepend or append the content
            provided to it.
        </para>
    </sect2>

    <sect2 id="zend.form.standardDecorators.htmlTag">
        <title>Zend_Form_Decorator_HtmlTag</title>

        <para>
            The HtmlTag decorator allows you to utilize <acronym>HTML</acronym> tags to
            decorate content; the tag utilized is passed in the 'tag'
            option, and any other options are used as <acronym>HTML</acronym> attributes to
            that tag. The tag by default is assumed to be block level, and
            replaces the content by wrapping it in the given tag. However,
            you can specify a placement to append or prepend a tag as well.
        </para>
    </sect2>

    <sect2 id="zend.form.standardDecorators.image">
        <title>Zend_Form_Decorator_Image</title>

        <para>
            The Image decorator allows you to create an <acronym>HTML</acronym> image input
            (<emphasis>&lt;input type="image" ... /&gt;</emphasis>), and optionally
            render it within another <acronym>HTML</acronym> tag.
        </para>

        <para>
            By default, the decorator uses the element's src property, which can
            be set with the <methodname>setImage()</methodname> method, as the image
            source. Additionally, the element's label will be used as the alt
            tag, and the <property>imageValue</property> (manipulated with the Image
            element's <methodname>setImageValue()</methodname> and
            <methodname>getImageValue()</methodname> accessors) will be used for the value.
        </para>

        <para>
            To specify an <acronym>HTML</acronym> tag with which to wrap the element, either pass a
            'tag' option to the decorator, or explicitly call
            <methodname>setTag()</methodname>.
        </para>
    </sect2>

    <sect2 id="zend.form.standardDecorators.label">
        <title>Zend_Form_Decorator_Label</title>

        <para>
            Form elements typically have labels, and the Label decorator is
            used to render these labels. It proxies to the FormLabel view
            helper, and pulls the element label using the
            <methodname>getLabel()</methodname> method of the element. If no label is
            present, none is rendered. By default, labels are translated when a
            translation adapter exists and a translation for the label exists.
        </para>

        <para>
            You may optionally specify a 'tag' option; if provided, it wraps
            the label in that block-level tag. If the 'tag' option is
            present, and no label present, the tag is rendered with no
            content. You can specify the class to use with the tag with the
            'class' option or by calling <methodname>setTagClass()</methodname>.
        </para>

        <para>
            Additionally, you can specify prefixes and suffixes to use when
            displaying the element, based on whether or not the label is for an
            optional or required element. Common use cases would be to append a
            ':' to the label, or a '*' indicating an item is required. You can
            do so with the following options and methods:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <property>optionalPrefix</property>: set the text to prefix the
                    label with when the element is optional. Use the
                    <methodname>setOptionalPrefix()</methodname> and
                    <methodname>getOptionalPrefix()</methodname> accessors to manipulate it.
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>optionalSuffix</property>: set the text to append the
                    label with when the element is optional. Use the
                    <methodname>setOptionalSuffix()</methodname> and
                    <methodname>getOptionalSuffix()</methodname> accessors to manipulate it.
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>requiredPrefix</property>: set the text to prefix the
                    label with when the element is required. Use the
                    <methodname>setRequiredPrefix()</methodname> and
                    <methodname>getRequiredPrefix()</methodname> accessors to manipulate it.
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>requiredSuffix</property>: set the text to append the
                    label with when the element is required. Use the
                    <methodname>setRequiredSuffix()</methodname> and
                    <methodname>getRequiredSuffix()</methodname> accessors to manipulate it.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            By default, the Label decorator prepends to the provided
            content; This can be controlled by specifying one of the following
            'placement' options:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <property>PREPEND</property>: render the label before the
                    content.
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>APPEND</property>: render the label after the
                    content.
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>IMPLICIT_PREPEND</property>: render the element
                    inside the label tag, placing the label text before the content.
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>IMPLICIT_APPEND</property>: render the element
                    inside the label tag, placing the label text after the content.
                </para>
            </listitem>
        </itemizedlist>

   </sect2>

    <sect2 id="zend.form.standardDecorators.prepareElements">
        <title>Zend_Form_Decorator_PrepareElements</title>

        <para>
            Forms, display groups, and sub forms are collections of
            elements. When using the <link
                linkend="zend.form.standardDecorators.viewScript">ViewScript</link>
            decorator with your form or sub form, it's useful to be able to
            recursively set the view object, translator, and all fully qualifid
            names (as determined by sub form array notation). The
            'PrepareElements' decorator can do this for you. Typically, you will
            set it as the first decorator in the list.
        </para>

        <programlisting language="php"><![CDATA[
$form->setDecorators(array(
    'PrepareElements',
    array('ViewScript', array('viewScript' => 'form.phtml')),
));
]]></programlisting>
    </sect2>

    <sect2 id="zend.form.standardDecorators.tooltip">
        <title>Zend_Form_Decorator_Tooltip</title>

        <para>
            The Tooltip decorator translates the title attribute if it is
            available, if the translator is available and if the translator is
            not disable on the element being rendered.
        </para>
    </sect2>

    <sect2 id="zend.form.standardDecorators.viewHelper">
        <title>Zend_Form_Decorator_ViewHelper</title>

        <para>
            Most elements utilize <classname>Zend_View</classname> helpers for
            rendering, and this is done with the ViewHelper decorator. With
            it, you may specify a 'helper' tag to explicitly set the view
            helper to utilize; if none is provided, it uses the last segment
            of the element's class name to determine the helper, prepending
            it with the string 'form': e.g., 'Zend_Form_Element_Text' would
            look for a view helper of 'formText'.
        </para>

        <para>
            Any attributes of the provided element are passed to the view
            helper as element attributes.
        </para>

        <para>
            By default, this decorator appends content; use the 'placement'
            option to specify alternate placement.
        </para>
    </sect2>

    <sect2 id="zend.form.standardDecorators.viewScript">
        <title>Zend_Form_Decorator_ViewScript</title>

        <para>
            Sometimes you may wish to use a view script for creating your
            elements; this way you can have fine-grained control over your
            elements, turn the view script over to a designer, or simply create
            a way to easily override setting based on which module you're using
            (each module could optionally override element view scripts to suit
            their own needs). The ViewScript decorator solves this problem.
        </para>

        <para>
            The ViewScript decorator requires a 'viewScript' option, either
            provided to the decorator, or as an attribute of the element. It
            then renders that view script as a partial script, meaning each call
            to it has its own variable scope; no variables from the view will be
            injected other than the element itself. Several variables are then
            populated:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <property>element</property>: the element being decorated
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>content</property>: the content passed to the decorator
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>decorator</property>: the decorator object itself
                </para>
            </listitem>

            <listitem>
                <para>
                    Additionally, all options passed to the decorator via
                    <methodname>setOptions()</methodname> that are not used internally (such
                    as placement, separator, etc.) are passed to the view script
                    as view variables.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            As an example, you might have the following element:
        </para>

        <programlisting language="php"><![CDATA[
// 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'))));
]]></programlisting>

        <para>
            You could then have a view script something like this:
        </para>

        <programlisting language="php"><![CDATA[
<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>
]]></programlisting>

        <note>
            <title>Replacing content with a view script</title>

            <para>
                You may find it useful for the view script to replace the
                content provided to the decorator -- for instance, if you want
                to wrap it. You can do so by specifying a boolean <constant>FALSE</constant> value
                for the decorator's 'placement' option:
            </para>

            <programlisting language="php"><![CDATA[
// At decorator creation:
$element->addDecorator('ViewScript', array('placement' => false));

// Applying to an existing decorator instance:
$decorator->setOption('placement', false);

// Applying to a decorator already attached to an element:
$element->getDecorator('ViewScript')->setOption('placement', false);

// Within a view script used by a decorator:
$this->decorator->setOption('placement', false);
]]></programlisting>
        </note>

        <para>
            Using the ViewScript decorator is recommended for when you want to
            have very fine-grained control over how your elements are rendered.
        </para>
    </sect2>
</sect1>
<!--
vim:se ts=4 sw=4 tw=80 et:
-->
