<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 15103 -->
<!-- Reviewed: no -->
<sect1 id="zend.form.standardDecorators">
    <title>Decoradores de Formulario (Form Decorartors) estándar contenidos en Zend Framework</title>

    <para>
        <classname>Zend_Form</classname> se distribuye con distintos decoradores estándar. Para más
        información sobre el uso de decoradores en general, vea <link
            linkend="zend.form.decorators">la sección sobre decoradores</link>.
    </para>

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

        <para>
            El decorador Callback (llamada de retorno) permite ejecutar una llamada de retorno para
            mostrar el contenido. Las llamadas de retorno deben especificarse a través
            de la opción 'callback' pasada en la configuración del decorador, y pueden
            ser de cualquier valor de llamada de retorno PHP. Los Callbacks deben
            aceptar tres argumentos: <methodname>$content</methodname> (el contenido original
            enviado al decorador), <methodname>$element</methodname> (el objeto que se está decorando),
            y un array de <methodname>$options</methodname>. Un callback de ejemplo sería:
        </para>

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

        <para>
            Esta llamada de retorno se especificaría como <methodname>array('Util',
                'label')</methodname>, y generaría un (mal) código HTML para
            la etiqueta. El decorador Callback reemplazará, antepondrá o postpondrá
            el contenido original con el que devuelva.
        </para>

        <para>
            El decorador Callback permite especificar un valor null para la opción
            placement (colocación), que reemplazará el contenido original
            con el valor devuelto de la llamada de retorno; 'prepend' (anteponer) y 'append' (postponer)
            siguen siendo válidas.
        </para>
    </sect2>

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

        <para>
            El decorador Captcha se usa junto con el <link
                linkend="zend.form.standardElements.captcha">elemento de formulario Captcha</link>. Utiliza el método
            <methodname>render()</methodname> del adaptador del captcha para generar la salida.
        </para>

        <para>
            Una variante del decorador Captcha, 'Captcha_Word', es usada frecuentemente,
            y crea dos elementos, un id y una entrada (input). El id indica
            el identificador de sesión que hay que comparar, y la entrada es para
            la verificación de usuario del captcha. Éstos elementos son validados
            como un sólo elemento.
        </para>
    </sect2>

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

        <para>
            El decorador Description puede ser usado para mostrar un conjunto de descripciones
            de un elemento <classname>Zend_Form</classname>, <methodname>Zend_Form_Element</methodname>, o
           <classname>Zend_Form_DisplayGroup</classname>; toma la descripción usando el método
            <methodname>getDescription()</methodname> del objeto.
        </para>

        <para>
            Por defecto, si no se encuentra la descripción, no se genera ninguna salida.
            Si la descripción está presente, entonces se envolverá en una etiqueta
            <methodname>p</methodname> HTML por defecto, aunque tiene la posibilidad de especificar
            una etiqueta pasando una opción <methodname>tag</methodname> al crear el decorador, o
            llamando a <methodname>setTag()</methodname>. También puede especificar una clase
            para el tag usando la opción <methodname>class</methodname> o llamando a
            <methodname>setClass()</methodname>; por defecto, se usa la clase 'hint'.
        </para>

        <para>
            La descripción es escapada utilizando los mecanismos de escapado por defecto
            del objeto de vista. Puede desactivar esto pasando un valor
            <methodname>false</methodname> a la opción 'escape' del decorador o el método
            <methodname>setEscape()</methodname>.
        </para>
    </sect2>

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

        <para>
            Los decoradores por defecto utilizan listas de definición
            (<methodname>&lt;dl&gt;</methodname>) para generar elementos de formulario (form).
            Dato que los elementos de formulario pueden aparecer en cualquier orden,
            grupos de visualización y subformularios pueden ser encapsulados dentro de
            otros elementos de formulario. Para mantener estos tipos de elemento particulares
            dentro de la lista de definición, DtDdWrapper crea una nuevo término de definición
            vacío (definition term)(<methodname>&lt;dt&gt;</methodname>) y encapsula su contenido
            en un nuevo dato de definición (<methodname>&lt;dd&gt;</methodname>).
            La salida queda como sigue:
        </para>

        <programlisting language="html"><![CDATA[
<dt></dt>
<dd><fieldset id="subform">
    <legend>Información de Usuario</legend>
    ...
</fieldset></dd>
]]></programlisting>

        <para>
            Este decorador reemplaza el contenido que se le provee
            envolviéndolo dentro del elemento <methodname>&lt;dd&gt;</methodname>.
        </para>
    </sect2>

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

        <para>
            Los errores de elemento obtienen su propio decorador con el decorador
            de errores. Este decorador sustituye al view helper FormErrors,
            que genera mensajes de error en una lista no ordenada
            (<methodname>&lt;ul&gt;</methodname>) como elementos de lista (li). El elemento
            <methodname>&lt;ul&gt;</methodname> recibe una clase de "errores".
        </para>

        <para>
            El decorador de Errores puede anteponerse o postponerse al contenido
            que se le provee.
        </para>
    </sect2>

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

        <para>
            Por defecto, los grupos de visualización y subformularios generan sus contenidos dentro
            de fieldsets, EL decorador Fieldset busca la opción
            'legend' o bien el método <methodname>getLegend()</methodname> en el elemento
            registrado, y lo usa como campo "legend" si no es vacío. Cualquier
            contenido pasado es envuelto en el fieldset HTML, reemplazando
            al contenido original. Cualquier atributo pasado al elemento decorado
            será generado como atributo del fieldset HTML.
        </para>
    </sect2>

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

        <para>
            Los elementos de tipo "File" (upload de ficheros) tienen una notación especial
            cuando se usan múltiples elementos file o subformularios. El decorador
            File es usado por <classname>Zend_Form_Element_File</classname> y permite fijar
            múltiples elementos file con una única llamada al método. Se usa automáticamente
            y fija el nombre de cada elemento.
        </para>
    </sect2>

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

        <para>
            Los objetos <classname>Zend_Form</classname> normalmente necesitan generar una etiqueta
            HTML "form". El decorador Form utiliza la ayuda del view helper Form. Encapsula
            cualquier contenido provista en un elemento HTML form, usando la acción y el
            método del objeto Zend Form, y cualquier atributo como atributo HTML.
        </para>
    </sect2>

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

        <para>
            Los formularios(forms), grupos de visualización y subformularios
            son colecciones de elementos. Para poder generar estos elementos,
            utilizan el decorador FormElements, el cual itera sobre todos los elementos,
            llamando a <methodname>render()</methodname> en cada uno de ellos y uniéndolos
            con el separador indicado. Puede anteponer o postponer al contenido que
            se le envía.
        </para>
    </sect2>

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

        <para>
            Algunos desarrolladores y diseñadores prefieren agrupar todos los
            mensajes de error en la parte superior del formulario. El decorador
            FormErrors le permite hacer esto.
        </para>

        <para>
            Por defecto, la lista de errores generada tiene el siguiente marcado:
        </para>

        <programlisting language="html"><![CDATA[
<ul class="form-errors">
    <li><b>[etiqueta de elemento o nombre]</b><ul>
            <li>[mensaje de error]</li>
            <li>[mensaje de error]</li>
        </ul>
    </li>
    <li><ul>
        <li><b>[etiqueta o nombre de elemento subformulario</b><ul>
                <li>[mensaje de error]</li>
                <li>[mensaje de error]</li>
            </ul>
        </li>
    </ul></li>
</ul>
]]></programlisting>

        <para>
            Puede pasar como parámetro varias opciones para configurar la salida generada:
        </para>

        <itemizedlist>
            <listitem><para>
                <methodname>ignoreSubForms</methodname>: se desactiva o no la recursividad
                en los subformularios. Por defecto: false (i.e., permitir recursividad).
            </para></listitem>

            <listitem><para>
                <methodname>markupElementLabelEnd</methodname>: Marcado para postponer las etiquetas de elementos. Por defecto: '&lt;/b&gt;'
            </para></listitem>

            <listitem><para>
                <methodname>markupElementLabelStart</methodname>: Marcado para anteponer las etiquetas de elementos. Por defecto'&lt;b&gt;'
            </para></listitem>

            <listitem><para>
                <methodname>markupListEnd</methodname>: Marcado para postponer listas de mensajes de error.  Por defecto: '&lt;/ul&gt;'.
            </para></listitem>

            <listitem><para>
                <methodname>markupListItemEnd</methodname>: Marcado para postponer mensajes de error individuales.  Por defecto: '&lt;/li&gt;'
            </para></listitem>

            <listitem><para>
                <methodname>markupListItemStart</methodname>: Marcado para anteponer mensajes de error individuales.  Por defecto: '&lt;li&gt;'
            </para></listitem>

            <listitem><para>
                <methodname>markupListStart</methodname>: Marcado para anteponer listas de mensajes de error.  Por defecto: '&lt;ul class="form-errors"&gt;'
            </para></listitem>
        </itemizedlist>

        <para>
            El decorador FormErrors puede anteponerse o postponerse al contenido
            que se le provee.
        </para>
    </sect2>

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

        <para>
            El decorador HtmlTag le permite utilizar etiquetas HTML para
            decorador el contenido; la etiqueta utiliza es pasada en la opción 'tag'
            , y cualquier otra opción es usada como atributo HTML de esa etiqueta.
            Por defecto, el contenido generado reemplaza al contenido envolviéndolo en
            la etiqueta dada. De cualquier forma, se permite especificar una
            localización de tipo 'append' (postponer) o 'prepend' (anteponer).
        </para>
    </sect2>

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

        <para>
            El decorador Image le permite crear un input HTML de tipo image
            (<methodname>&lt;input type="image" ... /&gt;</methodname>), y opcionalmente
            mostrarlo dentro de otro tag HTML.
        </para>

        <para>
            Por defecto, el decorador usa la propiedad src del elemento,
            que puede fijarse con el método <methodname>setImage()</methodname>, como la ruta
            de la imagen ('src'). Adicionalmente, la etiqueta del elemento será usada
            como la etiqueta 'alt', y <methodname>imageValue</methodname> (manipulado con los
            métodos <methodname>setImageValue()</methodname> y
            <methodname>getImageValue()</methodname>) será usada como el campo 'value'.
        </para>

        <para>
            Para especificar una etiqueta HTML que utilizar con el elemento, pase la opción
            'tag' al decorador, o llame explícitamente a
            <methodname>setTag()</methodname>.
        </para>
    </sect2>

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

        <para>
            Comúnmente, los elementos de formulario tienen etiquetas (labels) y se
            usa el decorador Label para generar esas etiquetas.
            Utiliza la ayuda del view helper FormLabel,
            y toma la etiqueta del elemento mediante el método
            <methodname>getLabel()</methodname> de ese elemento. Si no se encuentra
            la etiqueta, no se genera. Por defecto, las etiquetas se
            traducen cuando existe un adaptador de traducciones y existe una
            traducción para la etiqueta.
        </para>

        <para>
            Opcionalmente, se puede especificar la opción 'tag'; si se suministra, encapsula
            la etiqueta en la etiqueta HTML en cuestión. Si la opción está presenta
            pero no hay etiqueta, la etiqueta será generada sin contenido.
            Puede especificar la clase que usar con la etiqueta mediante la opción
            'class' o llamando a <methodname>setClass()</methodname>.
        </para>

        <para>
            Adicionalmente, se pueden especificar prefijos o sufijos que usar
            al mostrar en pantalla los elementos, basados en si la etiqueta es para
            un elemento opcional o requerido. Por ejemplo, podríamos querer
            añadir ':' a la etiqueta o un '*', indicando que el elemento es requerido.
            Se puede realizar con las siguientes opciones y métodos:
        </para>

        <itemizedlist>
            <listitem><para>
                    <methodname>optionalPrefix</methodname>: fija el texto antepuesto a la etiqueta
                    cuando el elemento es opcional. Utilice los accesores
                    <methodname>setOptionalPrefix()</methodname> y
                    <methodname>getOptionalPrefix()</methodname> para manipularlo.
            </para></listitem>

            <listitem><para>
                    <methodname>optionalSuffix</methodname>: fija el texto pospuesto a la etiqueta
                    cuando el elemento es opcional. Utilice los accesores
                    <methodname>setOptionalSuffix()</methodname> y
                    <methodname>getOptionalSuffix()</methodname> para manipularlo.
            </para></listitem>

            <listitem><para>
                    <methodname>requiredPrefix</methodname>: fija el texto antepuesto a la etiqueta
                    cuando el elemento es requerido. Utilice los accesores
                    <methodname>setRequiredPrefix()</methodname> y
                    <methodname>getRequiredPrefix()</methodname> para manipularlo.
            </para></listitem>

            <listitem><para>
                    <methodname>requiredSuffix</methodname>: fija el texto antepuesto a la etiqueta
                    cuando el elemento es requerido. Utilice los accesores
                    <methodname>setRequiredSuffix()</methodname> y
                    <methodname>getRequiredSuffix()</methodname> para manipularlo.
            </para></listitem>
        </itemizedlist>

        <para>
            Por defecto, el decorador Label antecede al contenido provisto;
            especifique la opción 'placement' (colocación) como 'append' para
            colocarlo después del contenido.
        </para>
    </sect2>

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

        <para>
            Formularios, grupos de visualización, y subformularios son colecciones
            de elementos. Al usar el decorador <link
                linkend="zend.form.standardDecorators.viewScript">ViewScript</link>
            con un formulario o subformulario, resulta útil el poder fijar
            recursívamente el objeto de vista, el traductor (translator)y todos los
            nombres relacionados (determinados por la notiación de tabla del subformulario).
            Esta tarea puede realizarse gracias al decorador
            'PrepareElements'. Normalmente, se indicará como el primer
            decorador en al lista.
        </para>

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

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

        <para>
            La mayoría de los elementos utiliza helpers <classname>Zend_View</classname>
            para generar el contenido, y esto se realiza con el decorador ViewHelper.
            Con él, se puede especificar una etiqueta 'helper' para fijar
            explicitamente el view helper que utilizar; si no se suministra ninguno,
            utiliza el último segmento del nombre de clase del elemento para determinar
            el helper, anteponiéndole la cadena 'form': e.g., 'Zend_Form_Element_Text'
            buscaría un view helper del tipo 'formText'.
        </para>

        <para>
            Cualquier atributo del elemento suministrado es pasado al view helper
            como atributo del elemento.
        </para>

        <para>
            Por defecto, este decorador postpone el contenido; utilice la opción 'placement'
            para especificar una localización distinta.
        </para>
    </sect2>

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

        <para>
            A veces es necesario usar un view script para crear elementos;
            De esta forma, se puede tener un control preciso sobre los elementos;
            entregar el view script a un diseñador, o simplemente crear
            una forma fácil de sobreescribir basado en el módulo que se esté usando.
            El decorador ViewScript soluciona este problema.
        </para>

        <para>
            El decorador ViewScript requiere una opción 'viewScript', o bien suministrada
            al decorador, o bien como atributo del elemento. Entonces genera ese script de vista como un
            script parcial, lo que significa que cada llamada a él tiene su propio espacio de variables;
            Ninguna variable de la vista será rellenada, aparte del elemento en sí. Distintas variables son
            entonces rellenadas:
        </para>

        <itemizedlist>
            <listitem><para>
                    <methodname>element</methodname>: el elemento decorado
            </para></listitem>

            <listitem><para>
                    <methodname>content</methodname>: el contenido pasado al decorador
            </para></listitem>

            <listitem><para>
                    <methodname>decorator</methodname>: el propio objeto decorador
            </para></listitem>

            <listitem><para>
                    Del mismo modo, todas las opciones pasadas al decorador a través de
                    <methodname>setOptions()</methodname> que no son usadas internamente (tales
                    como placement, separator, etc.) son pasadas como
                    variables de vista.
            </para></listitem>
        </itemizedlist>

        <para>
            Como ejemplo, se pueden tener el siguiente elemento:
        </para>

         <programlisting language="php"><![CDATA[
// Fija un decorador ViewScript a un único elemento ,
// especificando como opción el script de vista (obligatorio) y algunas opciones extra
$element->setDecorators(array(array('ViewScript', array(
    'viewScript' => '_element.phtml',
    'class'      => 'form element'
))));

// o especificando el viewScript como un atributo del elemento:
$element->viewScript = '_element.phtml';
$element->setDecorators(array(array('ViewScript',
                                    array('class' => 'form element'))));
]]></programlisting>

        <para>
            Un view script puede tener el siguiente aspecto:
        </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>Reemplazar contenido con un script de vista (view script)</title>

            <para>
                Resulta interesante que el script de vista reemplace el
                contenido provisto por el decorador -- por ejemplo, si desea encapsularlo.
                Puede hacer esto especificando un valor booleano false en la
                opción 'placement' del decorador:
            </para>

             <programlisting language="php"><![CDATA[
// En la creación del decorador:
$element->addDecorator('ViewScript', array('placement' => false));

// Aplicado a una instancia de un decorador ya existente:
$decorator->setOption('placement', false);

// Aplicado a un decorador ya asociado a un elemento:
$element->getDecorator('ViewScript')->setOption('placement', false);

// Dentro de un view script usado por un decorador:
$this->decorator->setOption('placement', false);
]]></programlisting>
        </note>

        <para>
            Se recomienda usar el decorador ViewScript cuando necesite un control
            muy preciso sobre cómo generados sus elementos.
        </para>
    </sect2>
</sect1>
<!--
vim:se ts=4 sw=4 tw=80 et:
-->
