<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 17175 -->
<!-- Reviewed: no -->
<sect1 id="zend.form.standardDecorators">
    <title>Décorateurs standards fournis avec Zend Framework</title>

    <para>
        <classname>Zend_Form</classname> est livré avec plusieurs décorateurs standards. Pour
        plus d'informations sur l'utilisation des décorateurs en général, voyez <link
        linkend="zend.form.decorators">la section sur les décorateurs</link>.
    </para>

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

        <para>
            Le décorateur Callback peut exécuter une fonction de rappel pour rendre du
            contenu. Les fonctions doivent être spécifiées grâce à l'option 'callback' passée à la
            configuration du décorateur, et peut être n'importe quelle fonction <acronym>PHP</acronym> valide. Les
            fonctions peuvent accepter 3 arguments , <varname>$content</varname> ( le contenu original
            passé au décorateur), <varname>$element</varname> (l'objet étant décoré), et un tableau
            d'options <varname>$options</varname>. Voici un exemple&#160;:
        </para>

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

        <para>
            Cette fonction de rappel devrait être spécifiée avec <code>array('Util',
            'label')</code>, et générera du (mauvais) code HTML pour le label. Le décorateur
            Callback remplacera, fera suivre ou précéder le contenu original avec la valeur qu'il
            retourne.
        </para>

        <para>
            Le décorateur Callback accepte qu'on lui passe une valeur nulle pour l'option de
            placement, ce qui remplacera le contenu original par le contenu décoré. 'prepend' et
            'append' restent cependant acceptés.
        </para>
    </sect2>

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

        <para>
            Le décorateur Captcha est à utiliser avec <link
            linkend="zend.form.standardElements.captcha">l'élément de formulaire CAPTCHA</link>. Il
            utilise la méthode <methodname>render()</methodname> de l'adaptateur de CAPTCHA pour générer son
            contenu.
        </para>

        <para>
            Une variante du décorateur Captcha, 'Captcha_Word', est aussi utilisée quelques
            fois et créer 2 éléments, un id et un input. L'id indique l'identifiant de session à
            comparer et l'input est pour la saisie du CAPTCHA. Ces 2 éléments sont validés comme un
            seul.
        </para>
    </sect2>

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

        <para>
            Le décorateur Description peut être utilisé pour afficher la description affectée
            à un <classname>Zend_Form</classname>, <classname>Zend_Form_Element</classname>, ou
            <classname>Zend_Form_DisplayGroup</classname>; il cherche cette description en utilisant
            <methodname>getDescription()</methodname> sur l'objet en question.
        </para>

        <para>
            Par défaut, si aucune description n'est présente, rien ne sera généré. Dans le cas
            contraire , la description est entourée d'un tag HTML <code>p</code> par défaut, même si
            vous pouvez passer le tag que vous voulez en utilisant l'option <code>tag</code> à la
            création du décorateur, ou en utilisant sa méthode <methodname>setTag()</methodname>. Vous pouvez
            aussi spécifier une classe pour le tag en renseignant l'option <code>class</code> ou en
            appelant <methodname>setClass()</methodname>.
        </para>

        <para>
            La description est échappée en utilisant le mécanisme de l'objet de vue par
            défaut. Vous pouvez désactiver cette fonctionnalité en passant <constant>FALSE</constant> à
            l'option 'escape' du décorateur ou via sa méthode <methodname>setEscape()</methodname>.
        </para>
    </sect2>

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

        <para>
            Les décorateurs par défaut utilisent des listes de définition
            (<code>&lt;dl&gt;</code>) pour rendre les éléments de formulaire. Comme les éléments
            d'un formulaire peuvent apparaître dans n'importe quel ordre, les groupe d'affichage et
            les sous-formulaires peuvent être encapsulés dedans. Afin de garder ces types d'éléments
            dans la liste de définition, DtDdWrapper crée une nouvelle définition vide
            (<code>&lt;dt&gt;</code>) et encapsule don contenu dans une nouvelle donnée de
            définition (<code>&lt;dd&gt;</code>). L'affichage ressemble alors à ceci&#160;:
        </para>

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

        <para>
            Ce décorateur remplace le contenu qu'on lui fournit par ce même contenu entouré de
            <code>&lt;dd&gt;</code>.
        </para>
    </sect2>

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

        <para>
            Les erreurs des éléments possèdent leur propre décorateur : 'Errors'. Celui-ci
            utilise l'aide de vue FormErrors, qui rend les messages d'erreur dans une liste non
            ordonnée (<code>&lt;ul&gt;</code>) qui reçoit la classe d'affichage "errors".
        </para>

        <para>Le décorateur 'Errors' peut faire suivre ou précéder son contenu.</para>
    </sect2>

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

        <para>
            Les groupes d'affichage et les sous-formulaires rendent leur contenu dans des
            balises HTML fieldsets par défaut. Le décorateur Fieldset vérifie une option 'legend' ou
            la méthode <methodname>getLegend()</methodname> dans l'élément, et l'utilise comme élément de
            légende si non vide. Tout contenu qu'on lui passe est entouré d'une balise HTML
            "fieldset", et remplace donc le contenu précédent. Tout attribut passé à l'élément
            décoré sera rendu comme attribut de la balise HTML fieldset.
        </para>
    </sect2>

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

        <para>
            Les éléments de type "File" (upload de fichiers) ont une notation spéciale lorsque
            vous utilisez de multiples éléments file ou des sous-formulaires. Le décorateur File est
            utilisé par <classname>Zend_Form_Element_File</classname> et autorise plusieurs éléments
            avec un seul appel de méthode. Il est utilisé automatiquement et gère alors le nom de
            chaque élément.
        </para>
    </sect2>

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

        <para>
            Les objets <classname>Zend_Form</classname> ont en général besoin de rendre une
            balise HTML "form". Le décorateur Form utilise l'aide de vue du même nom dans ce but. Il
            encapsule le contenu qu'on lui passe dans une balise HTML 'form' et remplace donc ce
            contenu par le nouveau entouré. Les action, méthode et attributs de l'objet
            <classname>Zend_Form</classname> sont bien entendus utilisés dans la balise.
        </para>
    </sect2>

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

        <para>
            Les formulaires, groupes d'affichage et sous-formulaires sont des collections
            d'éléments. Afin de rendre ces éléments, ils utilisent le décorateur FormElements, qui
            itère sur tous les éléments et appelle leur méthode <methodname>render()</methodname> en les
            joignant avec le séparateur. Il peut faire suivre ou précéder son contenu.
        </para>
    </sect2>

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

        <para>
            Certains développeurs ou designers préfèrent regrouper tous les messages d'erreur
            en haut du formulaire. Le décorateur FormErrors a été conçu dans ce but.
        </para>

        <para>Par défaut, la liste d'erreurs générée ressemble à ceci :</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>
            Vous pouvez lui passer un tas d'options afin de la configurer plus
            finement&#160;:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <code>ignoreSubForms</code>&#160;: ignore ou pas la récursion dans les
                    sous-formulaires. Par défaut&#160;: <constant>FALSE</constant> (autorise la
                    récursion).
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>markupElementLabelEnd</code>&#160;: balise à ajouter après le label des
                    éléments. Par défaut: '&lt;/b&gt;'
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>markupElementLabelStart</code>&#160;: balise à ajouter avant le label des
                    éléments. Par défaut: '&lt;b&gt;'
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>markupListEnd</code>&#160;: balise à ajouter après la liste des messages
                    d'erreur. Par défaut: '&lt;/ul&gt;'.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>markupListItemEnd</code>&#160;: balise à ajouter après chaque message
                    d'erreur. Par défaut: '&lt;/li&gt;'
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>markupListItemStart</code>&#160;: balise à ajouter avant chaque message
                    d'erreur. Par défaut: '&lt;li&gt;'
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>markupListStart</code>&#160;: balise à ajouter autour de la liste des
                    messages d'erreur. Par défaut: '&lt;ul class="form-errors"&gt;'
                </para>
            </listitem>
        </itemizedlist>

        <para>Le décorateur FormErrors peut faire suivre ou précéder son contenu.</para>
    </sect2>

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

        <para>
            Le décorateur HtmlTag vous permet d'utiliser une balise HTML pour décorer votre
            contenu. La balise utilisée est passée comme option 'tag' et toute autre option sera
            utilisée comme attribut HTML à cette balise. Par défaut, le contenu généré remplace le
            contenu reçu par le décorateur. Vous pouvez tout de même préciser un placement 'append'
            ou 'prepend'.
        </para>
    </sect2>

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

        <para>
            Le décorateur Image vous permet de créer un tag HTML d'image (<code>&lt;input
            type="image" ... /&gt;</code>), et optionnellement le rendre à l'intérieur d'une autre
            balise HTML.
        </para>

        <para>
            Par défaut, le décorateur utilise la propriété 'src' , qui peut être renseignée
            grâce à la méthode <methodname>setImage()</methodname> (avec la source de l'image). Aussi, le label
            de l'élément va être utilisé comme propriété 'alt' de la balise et le propriété
            <code>imageValue</code> (manipulée grâce à <methodname>setImageValue()</methodname> et
            <methodname>getImageValue()</methodname>) sera utilisée comme valeur.
        </para>

        <para>
            Pour spécifier une balise HTML à utiliser avec l'élément, passez l'option 'tag' au
            décorateur, ou utilisez sa méthode <methodname>setTag()</methodname>.
        </para>
    </sect2>

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

        <para>
            Les éléments de formulaire possèdent en général un label, et le décorateur du même
            nom permet de le rendre. Il utilise l'aide de vue FormLabel en récupérant le label de
            l'élément avec <methodname>getLabel()</methodname>. Si aucun label n'est présent, rien n'est rendu.
            Par défaut, les label sont traduits lorsqu'un objet de traduction existe.
        </para>

        <para>
            Vous pouvez aussi spécifier optionnellement une option 'tag'. Si celle-ci est
            précisée, alors le label sera encapsulé dans la balise HTML en question. Si la balise
            est présente mais qu'il n'y a pas de label, alors la balise est rendu seule. Vous pouvez
            utiliser aussi une classe <acronym>CSS</acronym> grâce à l'option 'class' ou la méthode
            <methodname>setClass()</methodname>.
        </para>

        <para>
            Aussi, vous pouvez utiliser les préfixes ou des suffixes à afficher pour
            l'élément, selon si celui-ci est requis ou pas. Par exemple on peut imaginer que tout
            label est suivi du caractère ":". Aussi, tout élément requis à la saisie pourrait
            comporter une étoile "*". Des méthodes existent pour effectuer cela :
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <code>optionalPrefix</code>: affecte le texte à préfixer au label si
                    l'élément est optionnel. <methodname>setOptionalPrefix()</methodname> et
                    <methodname>getOptionalPrefix()</methodname> existent aussi.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>optionalSuffix</code>: affecte le texte à suffixer au label si
                    l'élément est optionnel. <methodname>setOptionalSuffix()</methodname> et
                    <methodname>getOptionalSuffix()</methodname> existent aussi.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>requiredPrefix</code>: affecte le texte à préfixer au label si
                    l'élément est marqué comme requis.<methodname>setRequiredPrefix()</methodname> et
                    <methodname>getRequiredPrefix()</methodname> existent aussi.
                </para>
            </listitem>

            <listitem>
                <para>
                    <code>requiredSuffix</code>: affecte le texte à suffixer au label si
                    l'élément est marqué comme requis.<methodname>setRequiredSuffix()</methodname> et
                    <methodname>getRequiredSuffix()</methodname> existent aussi.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            Par défaut, le décorateur Label préfixe son rendu vis à vis du contenu qu'on lui
            passe à décorer. L'option 'placement' reste disponible avec comme autre valeur possible
            'append'
        </para>
    </sect2>

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

        <para>
            Les formulaires, les groupes d'affichage et les sous-formulaires sont des
            collections d'éléments. Lors de l'utilisation du décorateur <link
            linkend="zend.form.standardDecorators.viewScript">ViewScript</link> dans vos
            formulaires, il peut être utile de récursivement passer l'objet de vue, le traducteur et
            tous les noms réels (notation tableau des sous-formulaires) aux éléments. Cette tache
            peut être effectuée grâce au décorateur 'PrepareElements'. En général, vous le marquerez
            en tant que premier décorateur de la pile.
        </para>

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

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

        <para>
            Beaucoup d'éléments utilisent les aides de <classname>Zend_View</classname> pour
            leur propre rendu, et ceci est effectué grâce au décorateur ViewHelper. Avec lui, vous
            pouvez spécifier une option 'helper' pour lui indiquer explicitement l'aide de vue à
            utiliser. Si aucune ne lui est fournie, il utilise le nom de la classe de l'élément
            (moins le chemin : la dernière partie du nom de la classe) afin de déterminer l'aide de
            vue à utiliser. Par exemple, 'Zend_Form_Element_Text' cherchera l'aide de vue 'form' +
            'Text' soit 'formText'.
        </para>

        <para>
            Tout attributs ajoutés à l'élément sera passé à l'aide vue comme attribut de
            l'élément HTML résultant.
        </para>

        <para>Par défaut, ce décorateur fait suivre son contenu au contenu qu'on lui passe.</para>
    </sect2>

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

        <para>
            Quelques fois, vous pouvez avoir besoin d'un script de vue pour afficher vos
            éléments. Ceci vous permettra un placement très fin et détaillé, ou alors de changer la
            vue utilisée en fonction du module <acronym>MVC</acronym> dans lequel vous vous situez, par exemple.
        </para>

        <para>
            Le décorateur ViewScript nécessite une option 'viewScript'. Celle-ci peut aussi
            être passée à l'élément lui-même, via sa propriété 'viewScript'. Le décorateur rend
            alors ce script de vue comme un script partiel (ce qui signifie que chaque appel à lui
            possède son propre espace de variables). Plusieurs variables sont alors peuplées dans le
            script de vue&#160;:
        </para>

        <itemizedlist>
            <listitem>
                <para><code>element</code>&#160;: l'élément décoré</para>
            </listitem>

            <listitem>
                <para><code>content</code>&#160;: le contenu passé au décorateur</para>
            </listitem>

            <listitem>
                <para><code>decorator</code>&#160;: l'objet décorateur lui-même</para>
            </listitem>

            <listitem>
                <para>
                    Aussi, toute variable passée au décorateur via <methodname>setOptions()</methodname>
                    et qui n'est pas utilisée en interne (qui n'est pas 'placement', 'separator',
                    etc.) est alors passée comme variable de vue.
                </para>
            </listitem>
        </itemizedlist>

        <para>Voici un exemple&#160;:</para>

        <programlisting language="php"><![CDATA[
// Affectation d'un décorateur ViewScript à un seul élément
// en spécifiant comme option le script de vue (obligatoire) et d'autres options :
$element->setDecorators(array(array('ViewScript', array(
    'viewScript' => '_element.phtml',
    'class'      => 'form element'
))));

// OU spécifier le script de vue comme attribut de l'élément
$element->viewScript = '_element.phtml';
$element->setDecorators(array(array('ViewScript',
                                    array('class' => 'form element'))));
]]></programlisting>

        <para>Le script de vue pourrait alors ressembler à cela :</para>

        <programlisting language="php"><![CDATA[
<div class="<?= $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>Remplacer le contenu avec un script de vue</title>

            <para>
                Le contenu n'est pas remplacé par défaut, vous pouvez le demander en
                spécifiant l'option 'placement' du décorateur. Il existe plusieurs manières de
                faire&#160;:
            </para>

            <programlisting language="php"><![CDATA[
// A la création du décorateur:
$element->addDecorator('ViewScript', array('placement' => false));

// Application au décorateur déja existant:
$decorator->setOption('placement', false);

// Application au décorateur déja ajouté à un élément:
$element->getDecorator('ViewScript')->setOption('placement', false);

// Depuis un script de vue:
$this->decorator->setOption('placement', false);
]]></programlisting>
        </note>

        <para>
            L'utilisation du décorateur ViewScript est recommandée dans les cas où vous
            souhaitez avoir un placement HTML très détaillé et très fin de vos éléments.
        </para>
    </sect2>
</sect1>