TigerZF
🌐Español

78.4. Ayudantes de vista

En sus scripts de vista, a menudo es necesario realizar ciertas funciones complejas una y otra vez: por ejemplo, dar formato a una fecha, generar elementos de formulario o mostrar enlaces de acción. Puede usar clases ayudantes para realizar estos comportamientos por usted.

Un ayudante es simplemente una clase. Supongamos que queremos un ayudante llamado 'fooBar'. Por defecto, la clase se prefija con 'Zend_View_Helper_' (puede especificar un prefijo personalizado al establecer una ruta de ayudantes), y el último segmento del nombre de la clase es el nombre del ayudante; este segmento debe estar en TitleCapped; el nombre completo de la clase es entonces: Zend_View_Helper_FooBar. Esta clase debe contener como mínimo un único método, nombrado según el ayudante, en camelCase: fooBar().

[Note] Preste atención a las mayúsculas

Los nombres de los ayudantes siempre están en camelCase, es decir, nunca comienzan con un carácter en mayúscula. El propio nombre de la clase está en MixedCase, pero el método que realmente se ejecuta está en camelCase.

[Note] Ruta de ayudantes por defecto

La ruta de ayudantes por defecto siempre apunta a los ayudantes de vista de Zend Framework, es decir, 'Zend/View/Helper/'. Incluso si llama a setHelperPath() para sobrescribir las rutas existentes, esta ruta se establecerá para garantizar que los ayudantes por defecto funcionen.

Para usar un ayudante en su script de vista, llámelo usando $this->helperName(). Detrás de escena, Zend_View cargará la clase Zend_View_Helper_HelperName, creará una instancia de objeto de la misma, y llamará a su método helperName(). La instancia del objeto es persistente dentro de la instancia de Zend_View, y se reutiliza para todas las llamadas futuras a $this->helperName().

78.4.1. Ayudantes iniciales

Zend_View viene con un conjunto inicial de clases ayudantes, la mayoría de las cuales están relacionadas con la generación de elementos de formulario y realizan el escapado de salida apropiado automáticamente. Además, hay ayudantes para crear URLs basadas en rutas y listas HTML, así como para declarar variables. Los ayudantes actualmente distribuidos incluyen:

  • declareVars(): Principalmente para usar junto con strictVars(), este ayudante puede usarse para declarar variables de plantilla que pueden o no estar ya establecidas en el objeto de vista, así como para establecer valores por defecto. Los arrays pasados como argumentos al método se usarán para establecer valores por defecto; de lo contrario, si la variable no existe, se establece como una cadena vacía.

  • fieldset($name, $content, $attribs): Crea un fieldset XHTML. Si $attribs contiene una clave 'legend', ese valor se usará para la leyenda del fieldset. El fieldset rodeará el $content proporcionado al ayudante.

  • form($name, $attribs, $content): Genera un formulario XHTML. Todos los $attribs se escapan y se renderizan como atributos XHTML de la etiqueta form. Si $content está presente y no es un booleano FALSE, entonces ese contenido se renderiza dentro de las etiquetas de apertura y cierre del formulario; si $content es un booleano FALSE (por defecto), solo se genera la etiqueta de apertura del formulario.

  • formButton($name, $value, $attribs): Crea un elemento <button />.

  • formCheckbox($name, $value, $attribs, $options): Crea un elemento <input type="checkbox" />.

    Por defecto, cuando no se proporciona ningún $value y no hay $options presentes, se asume que '0' es el valor sin marcar y '1' el valor marcado. Si se pasa un $value pero no hay $options presentes, se asume que el valor marcado es el valor pasado. El valor sin marcar se implementa renderizando un elemento input oculto antes de renderizar la casilla de verificación.

    $options debe ser un array. Si el array está indexado, el primer valor es el valor marcado, y el segundo el valor sin marcar; todos los demás valores se ignoran. También puede pasar un array asociativo con las claves 'checked' y 'unChecked'. La clave 'disableHidden' puede establecerse en true para evitar la renderización del campo oculto para el valor sin marcar.

    Si se ha pasado $options, si $value coincide con el valor marcado, entonces el elemento se marcará como marcado. También puede marcar el elemento como marcado o sin marcar pasando un valor booleano para el atributo 'checked'.

    Lo anterior probablemente se resume mejor con algunos ejemplos:

    // '1' and '0' as checked/unchecked options; not checked
    echo $this->formCheckbox('foo');
    
    // '1' and '0' as checked/unchecked options; checked
    echo $this->formCheckbox('foo', null, array('checked' => true));
    
    // 'bar' and '0' as checked/unchecked options; not checked
    echo $this->formCheckbox('foo', 'bar');
    
    // 'bar' and '0' as checked/unchecked options; checked
    echo $this->formCheckbox('foo', 'bar', array('checked' => true));
    
    // 'bar' and 'baz' as checked/unchecked options; unchecked
    echo $this->formCheckbox('foo', null, null, array('bar', 'baz'));
    
    // 'bar' and 'baz' as checked/unchecked options; unchecked
    echo $this->formCheckbox('foo', null, null, array(
        'checked' => 'bar',
        'unChecked' => 'baz'
    ));
    
    // 'bar' and 'baz' as checked/unchecked options; checked
    echo $this->formCheckbox('foo', 'bar', null, array('bar', 'baz'));
    echo $this->formCheckbox('foo',
                             null,
                             array('checked' => true),
                             array('bar', 'baz'));
    
    // 'bar' and 'baz' as checked/unchecked options; unchecked
    echo $this->formCheckbox('foo', 'baz', null, array('bar', 'baz'));
    echo $this->formCheckbox('foo',
                             null,
                             array('checked' => false),
                             array('bar', 'baz'));
    

    En todos los casos, el marcado antepone un elemento oculto con el valor sin marcar; de esta manera, si el valor no está marcado, aun así obtendrá un valor válido devuelto a su formulario.

  • formErrors($errors, $options): Genera una lista no ordenada XHTML para mostrar errores. $errors debe ser una cadena o un array de cadenas; $options debe ser cualquier atributo que desee colocar en la etiqueta de lista de apertura.

    Puede especificar contenido alternativo de apertura, cierre y separador al renderizar los errores llamando a varios métodos en el ayudante:

    • setElementStart($string); por defecto es '<ul class="errors"%s"><li>', donde %s se reemplaza con los atributos especificados en $options.

    • setElementSeparator($string); por defecto es '</li><li>'.

    • setElementEnd($string); por defecto es '</li></ul>'.

  • formFile($name, $attribs): Crea un elemento <input type="file" />.

  • formHidden($name, $value, $attribs): Crea un elemento <input type="hidden" />.

  • formImage($name, $value, $attribs): Crea un elemento <input type="image" />.

    echo $this->formImage(
        'foo',
        'bar',
        array(
            'src' => 'images/button.png',
            'alt' => 'Button',
        )
    );
    // Output: <input type="image" name="foo" id="foo" src="images/button.png" value="bar" alt="Button" />
    
  • formLabel($name, $value, $attribs): Crea un elemento <label>, estableciendo el atributo for a $name, y el texto real de la etiqueta a $value. Si se pasa disable en attribs, no se devolverá nada.

  • formMultiCheckbox($name, $value, $attribs, $options, $listsep): Crea una lista de casillas de verificación. $options debe ser un array asociativo, y puede ser arbitrariamente profundo. $value puede ser un único valor o un array de valores seleccionados que coincidan con las claves del array $options. $listsep es un salto HTML ("<br />") por defecto. Por defecto, este elemento se trata como un array; todas las casillas de verificación comparten el mismo nombre y se envían como un array.

    // Using list separator ($listsep):
    
    echo '<ul><li>';
    echo $view->formMultiCheckbox(
        'foo',
        2,
        array(
            'class' => 'baz',
        ),
        array(
            1 => 'One',
            2 => 'Two',
            3 => 'Three',
        ),
        "</li>\n<li>"
    );
    echo '</li></ul>';
    
    /*
    Output:
    <ul>
        <li>
            <label for="foo-1">
                <input type="checkbox" name="foo[]" id="foo-1" value="1" class="baz" />One
            </label>
        </li>
        <li>
            <label for="foo-2">
                <input type="checkbox" name="foo[]" id="foo-2" value="2" checked="checked" class="baz" />Two
            </label>
        </li>
        <li>
            <label for="foo-3">
                <input type="checkbox" name="foo[]" id="foo-3" value="3" class="baz" />Three</label>
            </li>
        </ul>
    */
    
    // Using options for label elements:
    echo $this->formMultiCheckbox(
        'foo',
        2,
        array(
            'label_placement' => 'prepend',
            'label_class'     => 'baz',
        ),
        array(
            1 => 'One',
            2 => 'Two',
            3 => 'Three',
        )
    );
    
    /*
    Output:
    <label class="baz" for="foo-1">
        One<input type="checkbox" name="foo[]" id="foo-1" value="1" />
    </label>
    <br />
    <label class="baz" for="foo-2">
        Two<input type="checkbox" name="foo[]" id="foo-2" value="2" checked="checked" />
    </label>
    <br />
    <label class="baz" for="foo-3">
        Three<input type="checkbox" name="foo[]" id="foo-3" value="3" />
    </label>
    */
    
  • formNote($name, $value = null): Crea una simple nota de texto. (p. ej. como elemento para titulares en un objeto Zend_Form)

    echo $this->formNote(null, 'This is an example text.');
    // Output: This is an example text.
    
  • formPassword($name, $value, $attribs): Crea un elemento <input type="password" />.

  • formRadio($name, $value, $attribs, $options, $listsep): Crea una serie de elementos <input type="radio" />, uno por cada uno de los elementos de $options. En el array $options, la clave del elemento es el valor de la opción de radio, y el valor del elemento es la etiqueta de radio. El radio de $value se preseleccionará por usted.

    // Using list separator ($listsep)
    
    echo '<ul><li>';
    echo $this->formRadio(
        'foo',
        2,
        array(
            'class' => 'baz',
        ),
        array(
            1 => 'One',
            2 => 'Two',
            3 => 'Three',
        ),
        "</li>\n<li>"
    );
    echo '</li></ul>';
    
    /*
    Output:
    <ul>
        <li>
            <label for="foo-1">
                <input type="radio" name="foo" id="foo-1" value="1" class="baz" />One
            </label>
        </li>
        <li>
            <label for="foo-2">
                <input type="radio" name="foo" id="foo-2" value="2" checked="checked" class="baz" />Two
            </label>
        </li>
        <li>
            <label for="foo-3">
                <input type="radio" name="foo" id="foo-3" value="3" class="baz" />Three
            </label>
        </li>
    </ul>
    */
    
    // Using options for label elements:
    
    echo $this->formRadio(
        'foo',
        2,
        array(
            'label_placement' => 'prepend',
            'label_class'     => 'baz',
        ),
        array(
            1 => 'One',
            2 => 'Two',
            3 => 'Three',
        )
    );
    
    /*
    Output:
    <label class="baz" for="foo-1">
        One<input type="radio" name="foo" id="foo-1" value="1" />
    </label>
    <br />
    <label class="baz" for="foo-2">
        Two<input type="radio" name="foo" id="foo-2" value="2" checked="checked" />
    </label>
    <br />
    <label class="baz" for="foo-3">
        Three<input type="radio" name="foo" id="foo-3" value="3" />
    </label>
    */
    
  • formReset($name, $value, $attribs): Crea un elemento <input type="reset" />.

  • formSelect($name, $value, $attribs, $options): Crea un bloque <select>...</select>, con un <option> por cada uno de los elementos de $options. En el array $options, la clave del elemento es el valor de la opción, y el valor del elemento es la etiqueta de la opción. La(s) opción(es) de $value se preseleccionará(n) por usted.

    // Using option groups:
    
    echo $view->formSelect(
        'foo',
        2,
        array(
            'class' => 'baz',
        ),
        array(
            1     => 'One',
            'Two' => array(
                '2.1' => 'One',
                '2.2' => 'Two',
                '2.3' => 'Three',
            ),
            3     => 'Three',
        )
    );
    
    /*
    Output:
    <select name="foo" id="foo" class="baz">
        <option value="1" label="One">One</option>
        <optgroup id="foo-optgroup-Two" label="Two">
            <option value="2.1" label="One">One</option>
            <option value="2.2" label="Two">Two</option>
            <option value="2.3" label="Three">Three</option>
        </optgroup>
        <option value="3" label="Three">Three</option>
    </select>
    */
    
    // First example with 'multiple' option:
    
    echo $this->formSelect(
        'foo[]',
        2,
        null,
        array(
            1 => 'One',
            2 => 'Two',
            3 => 'Three',
        )
    );
    
    /*
    Output:
    <select name="foo[]" id="foo" multiple="multiple">
        <option value="1" label="One">One</option>
        <option value="2" label="Two" selected="selected">Two</option>
        <option value="3" label="Three">Three</option>
    </select>
    */
    
    // Second example with 'multiple' option:
    
    echo $this->formSelect(
        'foo',
        array(
            1,
            2,
        ),
        array(
            'multiple' => true,
        ),
        array(
            1 => 'One',
            2 => 'Two',
            3 => 'Three',
        )
    );
    
    /*
    Output:
    <select name="foo[]" id="foo" multiple="multiple">
        <option value="1" label="One" selected="selected">One</option>
        <option value="2" label="Two" selected="selected">Two</option>
        <option value="3" label="Three">Three</option>
    </select>
    */
    
  • formSubmit($name, $value, $attribs): Crea un elemento <input type="submit" />.

  • formText($name, $value, $attribs): Crea un elemento <input type="text" />.

  • formTextarea($name, $value, $attribs): Crea un bloque <textarea>...</textarea>.

  • url($urlOptions, $name, $reset, $encode): Crea una cadena URL basada en una ruta con nombre. $urlOptions debe ser un array asociativo de pares clave/valor usados por la ruta en particular.

    // Using without options: (current request is: user/id/1)
    echo $this->url();
    // Output: user/info/id/1
    
    // Set URL options:
    echo $this->url(
        array('controller' => 'user', 'action' => 'info', 'username' => 'foobar')
    );
    // Output: user/info/username/foobar
    
    // Using a route:
    $router->addRoute(
        'user',
        new Zend_Controller_Router_Route(
            'user/:username',
            array(
                'controller' => 'user',
                'action'     => 'info',
            )
        )
    );
    
    echo $this->url(array('name' => 'foobar'), 'user');
    // Output: user/foobar
    
    // Using reset: (current request is: user/id/1)
    echo $this->url(array('controller' => 'user', 'action' => 'info'), null, false);
    // Output: user/info/id/1
    
    echo $this->url(array('controller' => 'user', 'action' => 'info'), null, true);
    // Output: user/info
    
    // Using encode:
    echo $this->url(
        array('controller' => 'user', 'action' => 'info', 'username' => 'John Doe'), null, true, false
    );
    // Output: user/info/username/John Doe
    
    echo $this->url(
        array('controller' => 'user', 'action' => 'info', 'username' => 'John Doe'), null, true, false
    );
    // Output: user/info/username/John+Doe
    
  • serverUrl($requestUri = null): Ayudante para devolver la URL del servidor actual (opcionalmente con el URI de la petición).

    // Current server URL in the example is: http://www.example.com/foo.html
    
    echo $this->serverUrl();
    // Output: http://www.example.com
    
    echo $this->serverUrl(true);
    // Output: http://www.example.com/foo.html
    
    echo $this->serverUrl('/foo/bar');
    // Output: http://www.example.com/foo/bar
    
    echo $this->serverUrl()->getHost();
    // Output: www.example.com
    
    echo $this->serverUrl()->getScheme();
    // Output: http
    
    $this->serverUrl()->setHost('www.foo.com');
    $this->serverUrl()->setScheme('https');
    echo $this->serverUrl();
    // Output: https://www.foo.com
    
  • htmlList($items, $ordered, $attribs, $escape): genera listas ordenadas y no ordenadas basadas en los $items pasados. Si $items es un array multidimensional, se construirá una lista anidada. Si la marca $escape es TRUE (por defecto), los elementos individuales se escaparán usando los mecanismos de escape registrados en el objeto de vista; pase un valor FALSE si desea permitir marcado en sus listas.

Usar estos en sus scripts de vista es muy sencillo; aquí hay un ejemplo. Tenga en cuenta que todo lo que necesita hacer es llamarlos; se cargarán y se instanciarán a sí mismos a medida que se necesiten.

// inside your view script, $this refers to the Zend_View instance.
//
// say that you have already assigned a series of select options under
// the name $countries as array('us' => 'United States', 'il' =>
// 'Israel', 'de' => 'Germany').
?>
<form action="action.php" method="post">
    <p><label>Your Email:
<?php echo $this->formText('email', 'you@example.com', array('size' => 32)) ?>
    </label></p>
    <p><label>Your Country:
<?php echo $this->formSelect('country', 'us', null, $this->countries) ?>
    </label></p>
    <p><label>Would you like to opt in?
<?php echo $this->formCheckbox('opt_in', 'yes', null, array('yes', 'no')) ?>
    </label></p>
</form>

La salida resultante del script de vista se verá algo así:

<form action="action.php" method="post">
    <p><label>Your Email:
        <input type="text" name="email" value="you@example.com" size="32" />
    </label></p>
    <p><label>Your Country:
        <select name="country">
            <option value="us" selected="selected">United States</option>
            <option value="il">Israel</option>
            <option value="de">Germany</option>
        </select>
    </label></p>
    <p><label>Would you like to opt in?
        <input type="hidden" name="opt_in" value="no" />
        <input type="checkbox" name="opt_in" value="yes" checked="checked" />
    </label></p>
</form>

78.4.1.1. Ayudante de vista Action

El ayudante de vista Action permite que los scripts de vista despachen una acción de controlador dada; el resultado del objeto de respuesta tras el despacho se devuelve entonces. Estos pueden usarse cuando una acción en particular puede generar contenido reutilizable o contenido "en forma de widget".

Las acciones que resulten en un _forward() o una redirección se consideran no válidas, y devolverán una cadena vacía.

La API del ayudante de vista Action sigue la de la mayoría de los componentes MVC que invocan acciones de controlador: action($action, $controller, $module = null, array $params = array()). $action y $controller son obligatorios; si no se especifica ningún módulo, se asume el módulo por defecto.

Ejemplo 78.1. Uso básico del ayudante de vista Action

Como ejemplo, puede tener un CommentController con un método listAction() que desea invocar para obtener una lista de comentarios para la solicitud actual:

<div id="sidebar right">
    <div class="item">
        <?php echo $this->action('list',
                                 'comment',
                                 null,
                                 array('count' => 10)); ?>
    </div>
</div>

78.4.1.2. Ayudante BaseUrl

Aunque la mayoría de las URLs generadas por el framework tienen la URL base añadida automáticamente, los desarrolladores necesitarán anteponer la URL base a sus propias URLs para que las rutas a los recursos sean correctas.

El uso del ayudante BaseUrl es muy sencillo:

/*
 * The following assume that the base URL of the page/application is "/mypage".
 */

/*
 * Prints:
 * <base href="/mypage/" />
 */
<base href="<?php echo $this->baseUrl(); ?>" />

/*
 * Prints:
 * <link rel="stylesheet" type="text/css" href="/mypage/css/base.css" />
 */
<link rel="stylesheet" type="text/css"
     href="<?php echo $this->baseUrl('css/base.css'); ?>" />
[Note] Nota

Por simplicidad, eliminamos el archivo PHP de entrada (p. ej., "index.php") de la URL base contenida en Zend_Controller. Sin embargo, en algunas situaciones esto puede causar un problema. Si ocurre, use $this->getHelper('BaseUrl')->setBaseUrl() para establecer su propia BaseUrl.

78.4.1.3. Ayudante Currency

Mostrar valores de moneda localizados es una tarea común; el ayudante de vista Zend_Currency está pensado para simplificar esta tarea. Vea la documentación de Zend_Currency para los detalles de esta característica de localización. En esta sección, nos centraremos simplemente en el uso del ayudante de vista.

Hay varias formas de iniciar el ayudante de vista Currency:

  • Registrado, a través de una instancia previamente registrada en Zend_Registry.

  • Posteriormente, a través de la interfaz fluida.

  • Directamente, instanciando la clase.

Una instancia registrada de Zend_Currency es el uso preferido para este ayudante. Al hacerlo, puede seleccionar la moneda a usar antes de añadir el adaptador al registro.

Hay varias formas de seleccionar la moneda deseada. Primero, puede simplemente proporcionar una cadena de moneda; alternativamente, puede especificar un locale. La forma preferida es usar un locale, ya que esta información se detecta y selecciona automáticamente a través de las cabeceras del cliente HTTP proporcionadas cuando un usuario accede a su aplicación, y garantiza que la moneda proporcionada coincida con su locale.

[Note] Nota

Hablamos de "locales" en lugar de "idiomas" porque un idioma puede variar según la región geográfica en la que se usa. Por ejemplo, el inglés se habla en diferentes dialectos: inglés británico, inglés estadounidense, etc. Como una moneda siempre se correlaciona con un país, debe proporcionar un locale totalmente cualificado, lo que significa proporcionar tanto el idioma como la región. Por lo tanto, decimos "locale" en lugar de "idioma".

Ejemplo 78.2. Instancia registrada

Para usar una instancia registrada, simplemente cree una instancia de Zend_Currency y regístrela dentro de Zend_Registry usando Zend_Currency como su clave.

// our example currency
$currency = new Zend_Currency('de_AT');
Zend_Registry::set('Zend_Currency', $currency);

// within your view
echo $this->currency(1234.56);
// this returns '€ 1.234,56'

Si está más familiarizado con la interfaz fluida, también puede crear una instancia dentro de su vista y configurar el ayudante posteriormente.

Ejemplo 78.3. Dentro de la vista

Para usar la interfaz fluida, cree una instancia de Zend_Currency, llame al ayudante sin ningún parámetro, y llame al método setCurrency().

// within your view
$currency = new Zend_Currency('de_AT');
$this->currency()->setCurrency($currency)->currency(1234.56);
// this returns '€ 1.234,56'

Si está usando el ayudante sin Zend_View, también puede usarlo directamente.

Ejemplo 78.4. Uso directo

// our example currency
$currency = new Zend_Currency('de_AT');

// initiate the helper
$helper = new Zend_View_Helper_Currency($currency);
echo $helper->currency(1234.56); // this returns '€ 1.234,56'

Como ya se ha visto, el método currency() se usa para devolver la cadena de moneda. Simplemente llámelo con el valor que desea mostrar como moneda. También acepta algunas opciones que pueden usarse para cambiar el comportamiento y la salida del ayudante.

Ejemplo 78.5. Uso directo

// our example currency
$currency = new Zend_Currency('de_AT');

// initiate the helper
$helper = new Zend_View_Helper_Currency($currency);
echo $helper->currency(1234.56); // this returns '€ 1.234,56'
echo $helper->currency(1234.56, array('precision' => 1));
// this returns '€ 1.234,6'

Para obtener detalles sobre las opciones disponibles, busque el método toCurrency() de Zend_Currency.

78.4.1.4. Ayudante Cycle

El ayudante Cycle se usa para alternar un conjunto de valores.

Ejemplo 78.6. Uso básico del ayudante Cycle

Para añadir elementos al cycle, simplemente especifíquelos en el constructor o use la función assign(array $data)

<?php foreach ($this->books as $book):?>
  <tr style="background-color:<?php echo $this->cycle(array("#F0F0F0",
                                                            "#FFFFFF"))
                                              ->next()?>">
  <td><?php echo $this->escape($book['author']) ?></td>
</tr>
<?php endforeach;?>

// Moving in backwards order and assign function
$this->cycle()->assign(array("#F0F0F0","#FFFFFF"));
$this->cycle()->prev();
?>

La salida

<tr style="background-color:'#F0F0F0'">
   <td>First</td>
</tr>
<tr style="background-color:'#FFFFFF'">
   <td>Second</td>
</tr>

Ejemplo 78.7. Trabajar con dos o más cycles

Para usar dos cycles, debe especificar los nombres de los cycles. Simplemente establezca el segundo parámetro en el método cycle. $this->cycle(array("#F0F0F0","#FFFFFF"),'cycle2'). También puede usar la función setName($name).


<?php foreach ($this->books as $book):?>
  <tr style="background-color:<?php echo $this->cycle(array("#F0F0F0",
                                                            "#FFFFFF"))
                                              ->next()?>">
  <td><?php echo $this->cycle(array(1,2,3),'number')->next()?></td>
  <td><?php echo $this->escape($book['author'])?></td>
</tr>
<?php endforeach;?>

78.4.1.5. Ayudante Partial

El ayudante de vista Partial se usa para renderizar una plantilla especificada dentro de su propio ámbito de variables. El uso principal es para fragmentos de plantilla reutilizables con los que no necesita preocuparse por colisiones de nombres de variables. Además, le permiten especificar scripts de vista parcial de módulos específicos.

Un hermano de Partial, el ayudante de vista PartialLoop le permite pasar datos iterables, y renderizar un parcial para cada elemento.

[Note] Contador de PartialLoop

El ayudante de vista PartialLoop asigna a la vista una variable llamada partialCounter que pasa la posición actual del array al script de vista. Esto proporciona una manera fácil de tener colores alternos en filas de tabla, por ejemplo.

Ejemplo 78.8. Uso básico de Partials

El uso básico de los parciales es renderizar un fragmento de plantilla en su propio ámbito de vista. Considere el siguiente script parcial:

<?php // partial.phtml ?>
<ul>
    <li>From: <?php echo $this->escape($this->from) ?></li>
    <li>Subject: <?php echo $this->escape($this->subject) ?></li>
</ul>

Luego lo llamaría desde su script de vista usando lo siguiente:

<?php echo $this->partial('partial.phtml', array(
    'from' => 'Team Framework',
    'subject' => 'view partials')); ?>

Lo cual renderizaría:

<ul>
    <li>From: Team Framework</li>
    <li>Subject: view partials</li>
</ul>

[Note] ¿Qué es un modelo?

Un modelo usado con el ayudante de vista Partial puede ser uno de los siguientes:

  • Array. Si se pasa un array, debe ser asociativo, ya que sus pares clave/valor se asignan a la vista con las claves como variables de vista.

  • Objeto que implementa el método toArray(). Si se pasa un objeto y tiene un método toArray(), los resultados de toArray() se asignarán al objeto de vista como variables de vista.

  • Objeto estándar. Cualquier otro objeto asignará los resultados de object_get_vars() (esencialmente todas las propiedades públicas del objeto) al objeto de vista.

Si su modelo es un objeto, es posible que desee que se pase como un objeto al script parcial, en lugar de serializarlo en un array de variables. Puede hacer esto estableciendo la propiedad 'objectKey' del ayudante correspondiente:

// Tell partial to pass objects as 'model' variable
$view->partial()->setObjectKey('model');

// Tell partial to pass objects from partialLoop as 'model' variable
// in final partial view script:
$view->partialLoop()->setObjectKey('model');

Esta técnica es particularmente útil al pasar Zend_Db_Table_Rowsets a partialLoop(), ya que entonces tiene acceso completo a sus objetos de fila dentro de los scripts de vista, lo que le permite llamar métodos sobre ellos (como recuperar valores de filas padre o dependientes).

Ejemplo 78.9. Uso de PartialLoop para renderizar modelos iterables

Normalmente, querrá usar parciales en un bucle, para renderizar el mismo fragmento de contenido muchas veces; de esta manera puede poner grandes bloques de contenido repetido o lógica de visualización compleja en una única ubicación. Sin embargo, esto tiene un impacto en el rendimiento, ya que el ayudante partial necesita invocarse una vez por cada iteración.

El ayudante de vista PartialLoop ayuda a resolver este problema. Le permite pasar un elemento iterable (array u objeto que implemente Iterator) como modelo. Luego itera sobre este, pasando los elementos al script parcial como el modelo. Los elementos en el iterador pueden ser cualquier modelo que permita el ayudante de vista Partial.

Supongamos el siguiente script de vista parcial:

<?php // partialLoop.phtml ?>
    <dt><?php echo $this->key ?></dt>
    <dd><?php echo $this->value ?></dd>

Y el siguiente "modelo":

$model = array(
    array('key' => 'Mammal', 'value' => 'Camel'),
    array('key' => 'Bird', 'value' => 'Penguin'),
    array('key' => 'Reptile', 'value' => 'Asp'),
    array('key' => 'Fish', 'value' => 'Flounder'),
);

En su script de vista, podría entonces invocar el ayudante PartialLoop:

<dl>
<?php echo $this->partialLoop('partialLoop.phtml', $model) ?>
</dl>
<dl>
    <dt>Mammal</dt>
    <dd>Camel</dd>

    <dt>Bird</dt>
    <dd>Penguin</dd>

    <dt>Reptile</dt>
    <dd>Asp</dd>

    <dt>Fish</dt>
    <dd>Flounder</dd>
</dl>

Ejemplo 78.10. Renderizar parciales en otros módulos

A veces un parcial existirá en un módulo diferente. Si conoce el nombre del módulo, puede pasarlo como segundo argumento a partial() o partialLoop(), moviendo el argumento $model a la tercera posición.

Por ejemplo, si hay un parcial de paginador que desea usar que está en el módulo 'list', podría obtenerlo de la siguiente manera:

<?php echo $this->partial('pager.phtml', 'list', $pagerData) ?>

De esta manera, puede reutilizar parciales creados específicamente para otros módulos. Dicho esto, es probable que sea una mejor práctica colocar los parciales reutilizables en rutas de scripts de vista compartidas.


78.4.1.6. Ayudante Placeholder

El ayudante de vista Placeholder se usa para persistir contenido entre scripts de vista e instancias de vista. También ofrece algunas características útiles, como agregar contenido, capturar el contenido del script de vista para uso posterior, y añadir texto previo y posterior al contenido (y separadores personalizados para el contenido agregado).

Ejemplo 78.11. Uso básico de Placeholders

El uso básico de los placeholders es persistir datos de vista. Cada invocación del ayudante Placeholder espera un nombre de placeholder; el ayudante entonces devuelve un objeto contenedor de placeholder que puede manipular o simplemente mostrar con echo.

<?php $this->placeholder('foo')->set("Some text for later") ?>

<?php
    echo $this->placeholder('foo');
    // outputs "Some text for later"
?>

Ejemplo 78.12. Uso de Placeholders para agregar contenido

Agregar contenido a través de placeholders también puede ser útil a veces. Por ejemplo, su script de vista puede tener un array de variables del que desea recuperar mensajes para mostrar más tarde; un script de vista posterior puede entonces determinar cómo se renderizarán.

El ayudante de vista Placeholder usa contenedores que extienden ArrayObject, proporcionando un rico conjunto de características para manipular arrays. Además, ofrece una variedad de métodos para dar formato al contenido almacenado en el contenedor:

  • setPrefix($prefix) establece el texto con el que prefijar el contenido. Use getPrefix() en cualquier momento para determinar cuál es la configuración actual.

  • setPostfix($prefix) establece el texto con el que añadir al final del contenido. Use getPostfix() en cualquier momento para determinar cuál es la configuración actual.

  • setSeparator($prefix) establece el texto con el que separar el contenido agregado. Use getSeparator() en cualquier momento para determinar cuál es la configuración actual.

  • setIndent($prefix) puede usarse para establecer un valor de indentación para el contenido. Si se pasa un entero, se usará ese número de espacios; si se pasa una cadena, se usará la cadena. Use getIndent() en cualquier momento para determinar cuál es la configuración actual.

<!-- first view script -->
<?php $this->placeholder('foo')->exchangeArray($this->data) ?>
<!-- later view script -->
<?php
$this->placeholder('foo')->setPrefix("<ul>\n    <li>")
                         ->setSeparator("</li><li>\n")
                         ->setIndent(4)
                         ->setPostfix("</li></ul>\n");
?>

<?php
    echo $this->placeholder('foo');
    // outputs as unordered list with pretty indentation
?>

Debido a que los objetos contenedores de Placeholder extienden ArrayObject, también puede asignar contenido a una clave específica en el contenedor fácilmente, en lugar de simplemente empujarlo al contenedor. Se puede acceder a las claves ya sea como propiedades de objeto o como claves de array.

<?php $this->placeholder('foo')->bar = $this->data ?>
<?php echo $this->placeholder('foo')->bar ?>

<?php
$foo = $this->placeholder('foo');
echo $foo['bar'];
?>

Ejemplo 78.13. Uso de Placeholders para capturar contenido

En ocasiones puede tener contenido para un placeholder en un script de vista que es más fácil de crear como plantilla; el ayudante de vista Placeholder le permite capturar contenido arbitrario para su renderización posterior usando la siguiente API.

  • captureStart($type, $key) comienza a capturar contenido.

    $type debe ser una de las constantes APPEND o SET de Placeholder. Si es APPEND, el contenido capturado se añade a la lista de contenido actual en el placeholder; si es SET, el contenido capturado se usa como el único valor del placeholder (potencialmente reemplazando cualquier contenido anterior). Por defecto, $type es APPEND.

    $key puede usarse para especificar una clave específica en el contenedor de placeholder a la que desea que se capture el contenido.

    captureStart() bloquea la captura hasta que se llama a captureEnd(); no puede anidar la captura con el mismo contenedor de placeholder. Hacerlo generará una excepción.

  • captureEnd() detiene la captura de contenido, y lo coloca en el objeto contenedor según cómo se llamó a captureStart().

<!-- Default capture: append -->
<?php $this->placeholder('foo')->captureStart();
foreach ($this->data as $datum): ?>
<div class="foo">
    <h2><?php echo $datum->title ?></h2>
    <p><?php echo $datum->content ?></p>
</div>
<?php endforeach; ?>
<?php $this->placeholder('foo')->captureEnd() ?>

<?php echo $this->placeholder('foo') ?>
<!-- Capture to key -->
<?php $this->placeholder('foo')->captureStart('SET', 'data');
foreach ($this->data as $datum): ?>
<div class="foo">
    <h2><?php echo $datum->title ?></h2>
    <p><?php echo $datum->content ?></p>
</div>
 <?php endforeach; ?>
<?php $this->placeholder('foo')->captureEnd() ?>

<?php echo $this->placeholder('foo')->data ?>

78.4.1.6.1. Implementaciones concretas de Placeholder

Zend Framework se distribuye con varias implementaciones "concretas" de placeholder. Estas son para los placeholders de uso común: doctype, título de página y varios elementos <head>. En todos los casos, llamar al placeholder sin argumentos devuelve el propio elemento.

La documentación de cada elemento se cubre por separado, tal como se enlaza a continuación:

78.4.1.7. Ayudante Doctype

Los documentos HTML y XHTML válidos deben incluir una declaración DOCTYPE. Además de ser difíciles de recordar, estas también pueden afectar cómo deben renderizarse ciertos elementos en su documento (por ejemplo, el escapado de CDATA en elementos <script> y <style>.

El ayudante Doctype le permite especificar uno de los siguientes tipos:

  • XHTML11

  • XHTML1_STRICT

  • XHTML1_TRANSITIONAL

  • XHTML1_FRAMESET

  • XHTML1_RDFA

  • XHTML_BASIC1

  • HTML4_STRICT

  • HTML4_LOOSE

  • HTML4_FRAMESET

  • HTML5

También puede especificar un doctype personalizado siempre que esté bien formado.

El ayudante Doctype es una implementación concreta del ayudante Placeholder.

Ejemplo 78.14. Uso básico del ayudante Doctype

Puede especificar el doctype en cualquier momento. Sin embargo, los ayudantes que dependen del doctype para su salida solo lo reconocerán después de que lo haya establecido, así que el enfoque más sencillo es especificarlo en su bootstrap:

$doctypeHelper = new Zend_View_Helper_Doctype();
$doctypeHelper->doctype('XHTML1_STRICT');

Y luego imprimirlo en la parte superior de su script de layout:

<?php echo $this->doctype() ?>

Ejemplo 78.15. Recuperar el Doctype

Si necesita conocer el doctype, puede hacerlo llamando a getDoctype() sobre el objeto, que se devuelve al invocar el ayudante.

$doctype = $view->doctype()->getDoctype();

Normalmente, simplemente querrá saber si el doctype es XHTML o no; para esto, el método isXhtml() será suficiente:

if ($view->doctype()->isXhtml()) {
    // do something differently
}

También puede comprobar si el doctype representa un documento HTML5.

if ($view->doctype()->isHtml5()) {
    // do something differently
}

Ejemplo 78.16. Elegir un Doctype para usar con el protocolo Open Graph

Para implementar el protocolo Open Graph, puede especificar el doctype XHTML1_RDFA. Este doctype permite a un desarrollador usar el Resource Description Framework dentro de un documento XHTML.

$doctypeHelper = new Zend_View_Helper_Doctype();
$doctypeHelper->doctype('XHTML1_RDFA');

El doctype RDFa permite que XHTML se valide cuando se usa el atributo de meta tag 'property' según la especificación del protocolo Open Graph. Ejemplo dentro de un script de vista:

<?php echo $this->doctype('XHTML1_RDFA'); ?>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:og="http://opengraphprotocol.org/schema/">
<head>
   <meta property="og:type" content="musician" />

En el ejemplo anterior, establecimos la propiedad a og:type. El og hace referencia al espacio de nombres Open Graph que especificamos en la etiqueta html. El contenido identifica la página como perteneciente a un músico. Vea la documentación del protocolo Open Graph para las propiedades admitidas. El ayudante HeadMeta puede usarse para establecer estas meta tags del protocolo Open Graph de forma programática.

Así es como puede comprobar si el doctype está establecido a XHTML1_RDFA:

<?php echo $this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml"
      <?php if ($view->doctype()->isRdfa()): ?>
      xmlns:og="http://opengraphprotocol.org/schema/"
      xmlns:fb="http://www.facebook.com/2008/fbml"
      <?php endif; ?>
>

78.4.1.8. Ayudante de vista Gravatar

El ayudante de vista Gravatar se usa para recibir avatares del servicio de Gravatar.

Ejemplo 78.17. Uso básico del ayudante de vista Gravatar

// From a view script (using XHTML DOCTYPE):
echo $this->gravatar('example@example.com');

/* results in the following output:
    <img src="http://www.gravatar.com/avatar/23463b99b62a72f26ed677cc556c44e8?s=80&d=mm&r=g" />
 */

[Note] Nota

Por supuesto, podemos configurar este ayudante. Podemos cambiar la altura de la imagen (por defecto es de 80px), y añadir una clase CSS u otros atributos a la etiqueta de imagen. Lo anterior simplemente muestra el uso más básico.

[Warning] ¡Use una dirección de correo válida!

La dirección de correo electrónico que proporcione al ayudante debe ser válida. Esta clase no valida la dirección (solo el parámetro rating). Se recomienda validar su dirección de correo electrónico dentro de su capa de modelo.

Ejemplo 78.18. Uso avanzado del ayudante de vista Gravatar

Hay varias formas de configurar el gravatar devuelto. En la mayoría de los casos, puede pasar un array de opciones como segundo argumento al ayudante, o llamar a métodos sobre el objeto devuelto para configurarlo.

  • La opción img_size puede usarse para especificar una altura alternativa; alternativamente, llame a setImgSize().

  • La opción secure puede usarse para forzar el uso de SSL en la URI de imagen devuelta pasando un valor booleano true (o deshabilitando el uso de SSL pasando false). Alternativamente, llame al método setSecure(). (Por defecto, la configuración sigue la misma seguridad que la solicitud de página actual.)

  • Para añadir atributos a la imagen, pase un array de pares clave/valor como el tercer argumento al ayudante, o llame al método setAttribs().

// Within the view script (using HTML DOCTYPE)
echo $this->gravatar('example@example.com',
    array('imgSize' => 90, 'defaultImg' => 'monsterid', 'secure' => true),
    array('class' => 'avatar', 'title' => 'Title for this image')
);

// Or use mutator methods
$this->gravatar()
     ->setEmail('example@example.com')
     ->setImgSize(90)
     ->setDefaultImg(Zend_View_Helper_Gravatar::DEFAULT_MONSTERID)
     ->setSecure(true)
     ->setAttribs(array('class' => 'avatar', 'title' => 'Title for this image'));

/* Both generate the following output:
<img class="avatar" title="Title for this image"
    src="https://secure.gravatar.com/avatar/23463b99b62a72f26ed677cc556c44e8?s=90&d=monsterid&r=g" >
 */

78.4.1.8.1. Opciones

Opciones de Zend_Service_Gravatar

img_size

Un entero que describe la altura del avatar, en píxeles; por defecto es "80".

default_img

Imagen a devolver si el servicio de gravatar no puede encontrar coincidencia para la dirección de correo proporcionada. Por defecto es "mm", la imagen del "hombre misterioso".

rating

Clasificación de audiencia a la que confinar las imágenes devueltas. Por defecto es "g"; puede ser uno de "g", "pg", "r", o "x", en orden de menos ofensivo a más ofensivo.

secure

Si se debe cargar o no la imagen a través de una conexión SSL. Por defecto es lo que se detecta a partir de la solicitud actual.

78.4.1.9. Ayudante HeadLink

El elemento HTML <link> se usa cada vez más para enlazar una variedad de recursos para su sitio: hojas de estilo, feeds, favicons, trackbacks, y más. El ayudante HeadLink proporciona una interfaz simple para crear y agregar estos elementos para su posterior recuperación y salida en su script de layout.

El ayudante HeadLink tiene métodos especiales para añadir enlaces de hoja de estilo a su pila:

  • appendStylesheet($href, $media, $conditionalStylesheet, $extras)

  • offsetSetStylesheet($index, $href, $media, $conditionalStylesheet, $extras)

  • prependStylesheet($href, $media, $conditionalStylesheet, $extras)

  • setStylesheet($href, $media, $conditionalStylesheet, $extras)

El valor $media por defecto es 'screen', pero puede ser cualquier valor de media válido. $conditionalStylesheet es una cadena o un booleano FALSE, y se usará en el momento de la renderización para determinar si deben incluirse comentarios especiales para evitar la carga de la hoja de estilo en ciertas plataformas. $extras es un array de cualquier valor extra que desee añadir a la etiqueta.

Además, el ayudante HeadLink tiene métodos especiales para añadir enlaces 'alternate' a su pila:

  • appendAlternate($href, $type, $title, $extras)

  • offsetSetAlternate($index, $href, $type, $title, $extras)

  • prependAlternate($href, $type, $title, $extras)

  • setAlternate($href, $type, $title, $extras)

El método ayudante headLink() permite especificar todos los atributos necesarios para un elemento <link>, y le permite también especificar la ubicación: si el nuevo elemento reemplaza a todos los demás, se antepone (parte superior de la pila), o se añade (final de la pila).

El ayudante HeadLink es una implementación concreta del ayudante Placeholder.

Ejemplo 78.19. Uso básico del ayudante HeadLink

Puede especificar un headLink en cualquier momento. Normalmente, especificará enlaces globales en su script de layout, y enlaces específicos de la aplicación en sus scripts de vista de la aplicación. En su script de layout, en la sección <head>, mostrará entonces el ayudante con echo para generar su salida.

<?php // setting links in a view script:
$this->headLink()->appendStylesheet('/styles/basic.css')
                 ->headLink(array('rel' => 'icon',
                                  'href' => '/img/favicon.ico'),
                                  'PREPEND')
                 ->prependStylesheet('/styles/moz.css',
                                     'screen',
                                     true,
                                     array('id' => 'my_stylesheet'));
?>
<?php // rendering the links: ?>
<?php echo $this->headLink() ?>

78.4.1.10. Ayudante HeadMeta

El elemento HTML <meta> se usa para proporcionar meta información sobre su documento HTML -- normalmente palabras clave, juego de caracteres del documento, directivas de caché, etc. Las meta tags pueden ser de tipo 'http-equiv' o 'name', deben contener un atributo 'content', y también pueden tener los atributos modificadores 'lang' o 'scheme'.

El ayudante HeadMeta admite los siguientes métodos para establecer y añadir meta tags:

  • appendName($keyValue, $content, $conditionalName)

  • offsetSetName($index, $keyValue, $content, $conditionalName)

  • prependName($keyValue, $content, $conditionalName)

  • setName($keyValue, $content, $modifiers)

  • appendHttpEquiv($keyValue, $content, $conditionalHttpEquiv)

  • offsetSetHttpEquiv($index, $keyValue, $content, $conditionalHttpEquiv)

  • prependHttpEquiv($keyValue, $content, $conditionalHttpEquiv)

  • setHttpEquiv($keyValue, $content, $modifiers)

  • setCharset($charset)

Los siguientes métodos también se admiten con el doctype XHTML1_RDFA establecido con el ayudante Doctype:

  • appendProperty($property, $content, $modifiers)

  • offsetSetProperty($index, $property, $content, $modifiers)

  • prependProperty($property, $content, $modifiers)

  • setProperty($property, $content, $modifiers)

El elemento $keyValue se usa para definir un valor para la clave 'name' o 'http-equiv'; $content es el valor para la clave 'content', y $modifiers es un array asociativo opcional que puede contener claves para 'lang' y/o 'scheme'.

También puede establecer meta tags usando el método ayudante headMeta(), que tiene la siguiente firma: headMeta($content, $keyValue, $keyType = 'name', $modifiers = array(), $placement = 'APPEND'). $keyValue es el contenido para la clave especificada en $keyType, que debe ser 'name' o 'http-equiv'. $keyType también puede especificarse como 'property' si el doctype se ha establecido a XHTML1_RDFA. $placement puede ser 'SET' (sobrescribe todos los valores almacenados previamente), 'APPEND' (añadido al final de la pila), o 'PREPEND' (añadido a la parte superior de la pila).

HeadMeta sobrescribe cada uno de append(), offsetSet(), prepend(), y set() para forzar el uso de los métodos especiales mencionados anteriormente. Internamente, almacena cada elemento como un token stdClass, que luego serializa usando el método itemToString(). Esto le permite realizar comprobaciones sobre los elementos de la pila, y opcionalmente modificar estos elementos simplemente modificando el objeto devuelto.

El ayudante HeadMeta es una implementación concreta del ayudante Placeholder.

Ejemplo 78.20. Uso básico del ayudante HeadMeta

Puede especificar una nueva meta tag en cualquier momento. Normalmente, especificará reglas de caché del lado del cliente o palabras clave SEO.

Por ejemplo, si desea especificar palabras clave SEO, estaría creando una meta tag name con el nombre 'keywords' y el contenido las palabras clave que desea asociar con su página:

// setting meta keywords
$this->headMeta()->appendName('keywords', 'framework, PHP, productivity');

Si deseara establecer algunas reglas de caché del lado del cliente, establecería etiquetas http-equiv con las reglas que desea aplicar:

// disabling client-side cache
$this->headMeta()->appendHttpEquiv('expires',
                                   'Wed, 26 Feb 1997 08:21:57 GMT')
                 ->appendHttpEquiv('pragma', 'no-cache')
                 ->appendHttpEquiv('Cache-Control', 'no-cache');

Otro uso popular de las meta tags es establecer el tipo de contenido, el juego de caracteres y el idioma:

// setting content type and character set
$this->headMeta()->appendHttpEquiv('Content-Type',
                                   'text/html; charset=UTF-8')
                 ->appendHttpEquiv('Content-Language', 'en-US');

Si está sirviendo un documento HTML5, debería proporcionar el juego de caracteres así:

// setting character set in HTML5
$this->headMeta()->setCharset('UTF-8'); // Will look like <meta charset="UTF-8">

Como ejemplo final, una manera fácil de mostrar un mensaje de transición antes de una redirección es usando un "meta refresh":

// setting a meta refresh for 3 seconds to a new url:
$this->headMeta()->appendHttpEquiv('Refresh',
                                   '3;URL=http://www.some.org/some.html');

Cuando esté listo para colocar sus meta tags en el layout, simplemente muestre el ayudante con echo:

<?php echo $this->headMeta() ?>

Ejemplo 78.21. Uso de HeadMeta con el doctype XHTML1_RDFA

Habilitar el doctype RDFa con el ayudante Doctype habilita el uso del atributo 'property' (además de los estándar 'name' y 'http-equiv') con HeadMeta. Esto se usa comúnmente con el protocolo Open Graph de Facebook.

Por ejemplo, puede especificar un título de página y tipo de open graph de la siguiente manera:

$this->doctype(Zend_View_Helper_Doctype::XHTML1_RDFA);
$this->headMeta()->setProperty('og:title', 'my article title');
$this->headMeta()->setProperty('og:type', 'article');
echo $this->headMeta();

// output is:
//   <meta property="og:title" content="my article title" />
//   <meta property="og:type" content="article" />

78.4.1.11. Ayudante HeadScript

El elemento HTML <script> se usa ya sea para proporcionar elementos de scripting en línea del lado del cliente o para enlazar a un recurso remoto que contenga código de scripting del lado del cliente. El ayudante HeadScript le permite gestionar ambos.

El ayudante HeadScript admite los siguientes métodos para establecer y añadir scripts:

  • appendFile($src, $type = 'text/javascript', $attrs = array())

  • offsetSetFile($index, $src, $type = 'text/javascript', $attrs = array())

  • prependFile($src, $type = 'text/javascript', $attrs = array())

  • setFile($src, $type = 'text/javascript', $attrs = array())

  • appendScript($script, $type = 'text/javascript', $attrs = array())

  • offsetSetScript($index, $script, $type = 'text/javascript', $attrs = array())

  • prependScript($script, $type = 'text/javascript', $attrs = array())

  • setScript($script, $type = 'text/javascript', $attrs = array())

En el caso de los métodos *File(), $src es la ubicación remota del script a cargar; esto suele ser en forma de una URL o una ruta. Para los métodos *Script(), $script son las directivas de scripting del lado del cliente que desea usar en el elemento.

[Note] Establecer comentarios condicionales

HeadScript le permite envolver la etiqueta script en comentarios condicionales, lo que le permite ocultarla de navegadores específicos. Para añadir las etiquetas condicionales, pase el valor condicional como parte del parámetro $attrs en las llamadas al método.

Ejemplo 78.22. Headscript con comentarios condicionales

// adding scripts
$this->headScript()->appendFile(
    '/js/prototype.js',
    'text/javascript',
    array('conditional' => 'lt IE 7')
);

[Note] Evitar el envoltorio de comentarios de estilo HTML o CDATA en los scripts

Por defecto, HeadScript envolverá los scripts con comentarios HTML o los envolverá con cdata XHTML. Este comportamiento puede ser problemático cuando pretende usar la etiqueta script de una manera alternativa estableciendo el tipo a algo distinto de 'text/javascript'. Para evitar dicho escapado, pase un noescape con un valor de true como parte del parámetro $attrs en las llamadas al método.

Ejemplo 78.23. Crear una plantilla de jQuery con headScript

// jquery template
$template = '<div class="book">{{:title}}</div>';
$this->headScript()->appendScript(
    $template,
    'text/x-jquery-tmpl',
    array('id='tmpl-book', 'noescape' => true)
);

HeadScript también permite capturar scripts; esto puede ser útil si desea crear el script del lado del cliente de forma programática, y luego colocarlo en otro lugar. El uso para esto se mostrará en un ejemplo a continuación.

Finalmente, también puede usar el método headScript() para añadir rápidamente elementos script; la firma para esto es headScript($mode = 'FILE', $spec, $placement = 'APPEND'). $mode es 'FILE' o 'SCRIPT', dependiendo de si está enlazando un script o definiendo uno. $spec es ya sea el archivo de script a enlazar o el propio código fuente del script. $placement debe ser 'APPEND', 'PREPEND', o 'SET'.

HeadScript sobrescribe cada uno de append(), offsetSet(), prepend(), y set() para forzar el uso de los métodos especiales mencionados anteriormente. Internamente, almacena cada elemento como un token stdClass, que luego serializa usando el método itemToString(). Esto le permite realizar comprobaciones sobre los elementos de la pila, y opcionalmente modificar estos elementos simplemente modificando el objeto devuelto.

El ayudante HeadScript es una implementación concreta del ayudante Placeholder.

[Note] Use InlineScript para scripts en el cuerpo HTML

El ayudante hermano de HeadScript, InlineScript, debe usarse cuando desee incluir scripts en línea en el cuerpo HTML. Colocar scripts al final de su documento es una buena práctica para acelerar la entrega de su página, particularmente cuando se usan scripts de análisis de terceros.

[Note] Los atributos arbitrarios están deshabilitados por defecto

Por defecto, HeadScript solo renderizará los atributos <script> bendecidos por el W3C. Estos incluyen 'type', 'charset', 'defer', 'language', y 'src'. Sin embargo, algunos frameworks de javascript, notablemente Dojo, utilizan atributos personalizados para modificar el comportamiento. Para permitir tales atributos, puede habilitarlos a través del método setAllowArbitraryAttributes():

$this->headScript()->setAllowArbitraryAttributes(true);

Ejemplo 78.24. Uso básico del ayudante HeadScript

Puede especificar una nueva etiqueta script en cualquier momento. Como se señaló anteriormente, estos pueden ser enlaces a archivos de recursos externos o los propios scripts.

// adding scripts
$this->headScript()->appendFile('/js/prototype.js')
                   ->appendScript($onloadScript);

El orden a menudo es importante con la escritura de scripts del lado del cliente; puede que necesite garantizar que las bibliotecas se cargan en un orden específico debido a las dependencias que cada una tiene; use las diversas directivas append, prepend y offsetSet para ayudar en esta tarea:

// Putting scripts in order

// place at a particular offset to ensure loaded last
$this->headScript()->offsetSetFile(100, '/js/myfuncs.js');

// use scriptaculous effects (append uses next index, 101)
$this->headScript()->appendFile('/js/scriptaculous.js');

// but always have base prototype script load first:
$this->headScript()->prependFile('/js/prototype.js');

Cuando finalmente esté listo para generar la salida de todos los scripts en su script de layout, simplemente muestre el ayudante con echo:

<?php echo $this->headScript() ?>

Ejemplo 78.25. Capturar scripts usando el ayudante HeadScript

A veces necesita generar scripts del lado del cliente de forma programática. Aunque podría usar concatenación de cadenas, heredocs, y similares, a menudo es más fácil simplemente hacerlo creando el script e intercalando etiquetas PHP. HeadScript le permite hacer exactamente eso, capturándolo a la pila:

<?php $this->headScript()->captureStart() ?>
var action = '<?php echo $this->baseUrl ?>';
$('foo_form').action = action;
<?php $this->headScript()->captureEnd() ?>

Se hacen las siguientes suposiciones:

  • El script se añadirá a la pila. Si desea que reemplace la pila o se añada en la parte superior, necesitará pasar 'SET' o 'PREPEND', respectivamente, como primer argumento a captureStart().

  • Se asume que el tipo MIME del script es 'text/javascript'; si desea especificar un tipo diferente, necesitará pasarlo como el segundo argumento a captureStart().

  • Si desea especificar atributos adicionales para la etiqueta <script>, páselos en un array como tercer argumento a captureStart().


78.4.1.12. Ayudante HeadStyle

El elemento HTML <style> se usa para incluir hojas de estilo CSS en línea en el elemento HTML <head>.

[Note] Use HeadLink para enlazar archivos CSS

HeadLink debe usarse para crear elementos <link> para incluir hojas de estilo externas. HeadStyle se usa cuando desea definir sus hojas de estilo en línea.

El ayudante HeadStyle admite los siguientes métodos para establecer y añadir declaraciones de hoja de estilo:

  • appendStyle($content, $attributes = array())

  • offsetSetStyle($index, $content, $attributes = array())

  • prependStyle($content, $attributes = array())

  • setStyle($content, $attributes = array())

En todos los casos, $content son las declaraciones CSS reales. $attributes son cualquier atributo adicional que desee proporcionar a la etiqueta style: lang, title, media, o dir son todos permisibles.

[Note] Establecer comentarios condicionales

HeadStyle le permite envolver la etiqueta style en comentarios condicionales, lo que le permite ocultarla de navegadores específicos. Para añadir las etiquetas condicionales, pase el valor condicional como parte del parámetro $attributes en las llamadas al método.

Ejemplo 78.26. Headstyle con comentarios condicionales

// adding scripts
$this->headStyle()->appendStyle($styles, array('conditional' => 'lt IE 7'));

HeadStyle también permite capturar declaraciones de estilo; esto puede ser útil si desea crear las declaraciones de forma programática, y luego colocarlas en otro lugar. El uso para esto se mostrará en un ejemplo a continuación.

Finalmente, también puede usar el método headStyle() para añadir rápidamente elementos de declaración; la firma para esto es headStyle($content$placement = 'APPEND', $attributes = array()). $placement debe ser 'APPEND', 'PREPEND', o 'SET'.

HeadStyle sobrescribe cada uno de append(), offsetSet(), prepend(), y set() para forzar el uso de los métodos especiales mencionados anteriormente. Internamente, almacena cada elemento como un token stdClass, que luego serializa usando el método itemToString(). Esto le permite realizar comprobaciones sobre los elementos de la pila, y opcionalmente modificar estos elementos simplemente modificando el objeto devuelto.

El ayudante HeadStyle es una implementación concreta del ayudante Placeholder.

[Note] Se usa la codificación UTF-8 por defecto

Por defecto, Zend Framework usa UTF-8 como su codificación por defecto, y, específicamente en este caso, Zend_View también. La codificación de caracteres puede establecerse de manera diferente en el propio objeto de vista usando el método setEncoding() (o el parámetro de instanciación encoding). Sin embargo, dado que Zend_View_Interface no define accesores para la codificación, es posible que si está usando una implementación de vista personalizada con este ayudante de vista, no tenga un método getEncoding(), que es lo que el ayudante de vista usa internamente para determinar el juego de caracteres en el que codificar.

Si no desea utilizar UTF-8 en tal situación, deberá implementar un método getEncoding() en su implementación de vista personalizada.

Ejemplo 78.27. Uso básico del ayudante HeadStyle

Puede especificar una nueva etiqueta style en cualquier momento:

// adding styles
$this->headStyle()->appendStyle($styles);

El orden es muy importante con CSS; puede que necesite garantizar que las declaraciones se cargan en un orden específico debido al orden de la cascada; use las diversas directivas append, prepend y offsetSet para ayudar en esta tarea:

// Putting styles in order

// place at a particular offset:
$this->headStyle()->offsetSetStyle(100, $customStyles);

// place at end:
$this->headStyle()->appendStyle($finalStyles);

// place at beginning
$this->headStyle()->prependStyle($firstStyles);

Cuando finalmente esté listo para generar la salida de todas las declaraciones de estilo en su script de layout, simplemente muestre el ayudante con echo:

<?php echo $this->headStyle() ?>

Ejemplo 78.28. Capturar declaraciones de estilo usando el ayudante HeadStyle

A veces necesita generar declaraciones de estilo CSS de forma programática. Aunque podría usar concatenación de cadenas, heredocs, y similares, a menudo es más fácil simplemente hacerlo creando los estilos e intercalando etiquetas PHP. HeadStyle le permite hacer exactamente eso, capturándolo a la pila:

<?php $this->headStyle()->captureStart() ?>
body {
    background-color: <?php echo $this->bgColor ?>;
}
<?php $this->headStyle()->captureEnd() ?>

Se hacen las siguientes suposiciones:

  • Las declaraciones de estilo se añadirán a la pila. Si desea que reemplacen la pila o se añadan en la parte superior, necesitará pasar 'SET' o 'PREPEND', respectivamente, como primer argumento a captureStart().

  • Si desea especificar atributos adicionales para la etiqueta <style>, páselos en un array como segundo argumento a captureStart().


78.4.1.13. Ayudante HeadTitle

El elemento HTML <title> se usa para proporcionar un título para un documento HTML. El ayudante HeadTitle le permite crear y almacenar el título de forma programática para su posterior recuperación y salida.

El ayudante HeadTitle es una implementación concreta del ayudante Placeholder. Sobrescribe el método toString() para forzar la generación de un elemento <title>, y añade un método headTitle() para el establecimiento y agregación rápidos y sencillos de elementos title. La firma para ese método es headTitle($title, $setType = null); por defecto, el valor se añade a la pila (agregando segmentos de título) si se deja en null, pero también puede especificar 'PREPEND' (colocar en la parte superior de la pila) o 'SET' (sobrescribir la pila).

Dado que establecer el orden de agregación (adjunto) en cada llamada a headTitle puede ser engorroso, puede establecer un orden de adjunto por defecto llamando a setDefaultAttachOrder(), que se aplica a todas las llamadas a headTitle() a menos que pase explícitamente un orden de adjunto diferente como segundo parámetro.

Ejemplo 78.29. Uso básico del ayudante HeadTitle

Puede especificar una etiqueta title en cualquier momento. Un uso típico tendría que establecer segmentos de título para cada nivel de profundidad en su aplicación: sitio, controlador, acción y potencialmente recurso.

 // setting the controller and action name as title segments:
$request = Zend_Controller_Front::getInstance()->getRequest();
$this->headTitle($request->getActionName())
     ->headTitle($request->getControllerName());

// setting the site in the title; possibly in the layout script:
$this->headTitle('Zend Framework');

// setting a separator string for segments:
$this->headTitle()->setSeparator(' / ');

Cuando finalmente esté listo para renderizar el título en su script de layout, simplemente muestre el ayudante con echo:

<!-- renders <action> / <controller> / Zend Framework -->
<?php echo $this->headTitle() ?>

78.4.1.14. Ayudantes de objetos HTML

El elemento HTML <object> se usa para incrustar medios como Flash o QuickTime en páginas web. Los ayudantes de vista de objeto se encargan de incrustar medios con el mínimo esfuerzo.

Hay cuatro ayudantes de objeto iniciales:

  • htmlFlash() Genera marcado para incrustar archivos Flash.

  • htmlObject() Genera marcado para incrustar un objeto personalizado.

  • htmlPage() Genera marcado para incrustar otras páginas (X)HTML.

  • htmlQuicktime() Genera marcado para incrustar archivos QuickTime.

Todos estos ayudantes comparten una interfaz similar. Por esta razón, esta documentación solo contendrá ejemplos de dos de estos ayudantes.

Ejemplo 78.30. Ayudante Flash

Incrustar Flash en su página usando el ayudante es bastante sencillo. El único argumento requerido es la URI del recurso.

<?php echo $this->htmlFlash('/path/to/flash.swf'); ?>

Esto genera el siguiente HTML:

<object data="/path/to/flash.swf"
        type="application/x-shockwave-flash"
        classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
        codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
</object>

Además, puede especificar atributos, parámetros y contenido que se pueden renderizar junto con el <object>. Esto se demostrará usando el ayudante htmlObject().

Ejemplo 78.31. Personalizar el objeto pasando argumentos adicionales

El primer argumento en los ayudantes de objeto siempre es obligatorio. Es la URI del recurso que desea incrustar. El segundo argumento solo es requerido en el ayudante htmlObject(). Los demás ayudantes ya contienen el valor correcto para este argumento. El tercer argumento se usa para pasar atributos al elemento object. Solo acepta un array con pares clave-valor. classid y codebase son ejemplos de tales atributos. El cuarto argumento también solo toma un array clave-valor y los usa para crear elementos <param>. Verá un ejemplo de esto en breve. Por último, está la opción de proporcionar contenido adicional al objeto. Ahora un ejemplo que utiliza todos los argumentos.

echo $this->htmlObject(
    '/path/to/file.ext',
    'mime/type',
    array(
        'attr1' => 'aval1',
        'attr2' => 'aval2'
    ),
    array(
        'param1' => 'pval1',
        'param2' => 'pval2'
    ),
    'some content'
);

/*
This would output:

<object data="/path/to/file.ext" type="mime/type"
    attr1="aval1" attr2="aval2">
    <param name="param1" value="pval1" />
    <param name="param2" value="pval2" />
    some content
</object>
*/

78.4.1.15. Ayudante InlineScript

El elemento HTML <script> se usa ya sea para proporcionar elementos de scripting en línea del lado del cliente o para enlazar a un recurso remoto que contenga código de scripting del lado del cliente. El ayudante InlineScript le permite gestionar ambos. Se deriva de HeadScript, y cualquier método de ese ayudante está disponible; sin embargo, use el método inlineScript() en lugar de headScript().

[Note] Use InlineScript para scripts en el cuerpo HTML

InlineScript debe usarse cuando desee incluir scripts en línea en el cuerpo HTML. Colocar scripts al final de su documento es una buena práctica para acelerar la entrega de su página, particularmente cuando se usan scripts de análisis de terceros.

Algunas bibliotecas JS necesitan incluirse en el head HTML; use HeadScript para esos scripts.

78.4.1.16. Ayudante RenderToPlaceholder

Renderiza una plantilla (script de vista) y almacena la salida renderizada como una variable de placeholder para uso posterior.

[Note] Nota

El ayudante usa el ayudante Placeholder y sus métodos de captura.

Ejemplo 78.32. Uso básico de RenderToPlaceholder

<?php
// View script (backlink.phtml):
echo sprintf(
    '<p class="older"><a href="%s">Older posts</a></p>',
    $this->url(array('controller' => 'index', 'action' => 'index'))
)
?>

<?php
// Usage:
$this->renderToPlaceholder('backlink.phtml', 'link');
?>

<?php
echo $this->placeholder('link');
// Output: <p class="older"><a href="index/index">Older posts</a></p>
?>

78.4.1.17. Ayudante JSON

Al crear vistas que devuelven JSON, es importante también establecer la cabecera de respuesta apropiada. El ayudante de vista JSON hace exactamente eso. Además, por defecto, deshabilita los layouts (si están habilitados actualmente), ya que los layouts generalmente no se usan con respuestas JSON.

El ayudante JSON establece la siguiente cabecera:

Content-Type: application/json

La mayoría de las bibliotecas AJAX buscan esta cabecera al analizar las respuestas para determinar cómo manejar el contenido.

El uso del ayudante JSON es muy sencillo:

<?php echo $this->json($this->data) ?>
[Note] Mantener layouts y habilitar la codificación usando Zend_Json_Expr

Cada método en el ayudante JSON acepta un segundo argumento opcional. Este segundo argumento puede ser una marca booleana para habilitar o deshabilitar los layouts, o un array de opciones que se pasará a Zend_Json::encode() y se usará internamente para codificar los datos.

Para mantener los layouts, el segundo parámetro debe ser booleano TRUE. Cuando el segundo parámetro es un array, mantener los layouts puede lograrse incluyendo una clave keepLayouts con un valor booleano TRUE.

// Boolean true as second argument enables layouts:
echo $this->json($this->data, true);

// Or boolean true as "keepLayouts" key:
echo $this->json($this->data, array('keepLayouts' => true));

Zend_Json::encode permite la codificación de expresiones JSON nativas usando objetos Zend_Json_Expr. Esta opción está deshabilitada por defecto. Para habilitar esta opción, pase un booleano TRUE a la clave enableJsonExprFinder del array de opciones:

<?php echo $this->json($this->data, array(
    'enableJsonExprFinder' => true,
    'keepLayouts'          => true,
)) ?>
[Note] Envío de JSON pre-codificado

Por defecto, el ayudante JSON codificará en JSON los datos proporcionados al primer parámetro del ayudante. Si desea pasar datos que ya se han codificado en JSON, el tercer parámetro debe establecerse en booleano FALSE. Cuando el segundo parámetro es un array, la codificación JSON puede deshabilitarse incluyendo una clave encodeData con el valor booleano FALSE:

// Boolean false as third argument disables internal JSON encoding of data
echo $this->json($this->data, false, false);

// Or boolean false as "encodeData" key:
echo $this->json($this->data, array('encodeData' => false));

78.4.1.18. Ayudantes de navegación

Los ayudantes de navegación se usan para renderizar elementos de navegación a partir de instancias de Zend_Navigation_Container.

Hay 5 ayudantes incorporados:

  • Breadcrumbs, usado para renderizar la ruta a la página actualmente activa.

  • Links, usado para renderizar enlaces de navegación en el head (p. ej. <link rel="next" href="..." />)

  • Menu, usado para renderizar menús.

  • Sitemap, usado para renderizar sitemaps conformes al formato XML de Sitemaps.

  • Navigation, usado para delegar llamadas a otros ayudantes de navegación.

Todos los ayudantes incorporados extienden Zend_View_Helper_Navigation_HelperAbstract, que añade integración con ACL y traducción. La clase abstracta implementa la interfaz Zend_View_Helper_Navigation_Helper, que define los siguientes métodos:

  • getContainer() y setContainer() obtienen y establecen el contenedor de navegación sobre el que el ayudante debe operar por defecto, y hasContainer() comprueba si el ayudante tiene un contenedor registrado.

  • getTranslator() y setTranslator() obtienen y establecen el traductor usado para traducir etiquetas y títulos. getUseTranslator() y setUseTranslator() controlan si el traductor debe estar habilitado. El método hasTranslator() comprueba si el ayudante tiene un traductor registrado.

  • getAcl(), setAcl(), getRole() y setRole(), obtienen y establecen la instancia ACL (Zend_Acl) y el rol (String o Zend_Acl_Role_Interface) usados para filtrar páginas al renderizar. getUseAcl() y setUseAcl() controlan si el ACL debe estar habilitado. Los métodos hasAcl() y hasRole() comprueban si el ayudante tiene una instancia ACL o un rol registrados.

  • __toString(), método mágico para garantizar que los ayudantes puedan renderizarse mostrando la instancia del ayudante directamente con echo.

  • render(), debe ser implementado por los ayudantes concretos para realizar la renderización real.

Además de los stubs de métodos de la interfaz, la clase abstracta también implementa los siguientes métodos:

  • getIndent() y setIndent() obtienen y establecen la indentación. El setter acepta un String o un Integer. En el caso de un Integer, el ayudante usará el número dado de espacios para la indentación. Es decir, setIndent(4) significa 4 espacios iniciales de indentación. La indentación puede especificarse para todos los ayudantes excepto el ayudante Sitemap.

  • getMinDepth() y setMinDepth() obtienen y establecen la profundidad mínima que debe tener una página para ser incluida por el ayudante. Establecer NULL significa que no hay profundidad mínima.

  • getMaxDepth() y setMaxDepth() obtienen y establecen la profundidad máxima que puede tener una página para ser incluida por el ayudante. Establecer NULL significa que no hay profundidad máxima.

  • getRenderInvisible() y setRenderInvisible() obtienen y establecen si se deben renderizar los elementos que se han marcado como invisibles o no.

  • __call() se usa para delegar llamadas al contenedor registrado en el ayudante, lo que significa que puede llamar métodos sobre un ayudante como si fuera un contenedor. Vea el ejemplo a continuación.

  • findActive($container, $minDepth, $maxDepth) se usa para encontrar la página activa más profunda en el contenedor dado. Si no se dan profundidades, el método usará los valores obtenidos de getMinDepth() y getMaxDepth(). La página activa más profunda debe estar entre $minDepth y $maxDepth inclusive. Devuelve un array que contiene una referencia a la instancia de página encontrada y la profundidad a la que se encontró la página.

  • htmlify() renderiza un elemento HTML 'a' a partir de una instancia de Zend_Navigation_Page.

  • accept() se usa para determinar si una página debe aceptarse al iterar contenedores. Este método comprueba la visibilidad de la página y verifica que el rol del ayudante tenga acceso permitido al recurso y privilegio de la página.

  • El método estático setDefaultAcl() se usa para establecer un objeto ACL por defecto que usarán los ayudantes.

  • El método estático setDefaultRole() se usa para establecer un ACL por defecto que usarán los ayudantes

Si un contenedor de navegación no se establece explícitamente en un ayudante usando $helper->setContainer($nav), el ayudante buscará una instancia de contenedor con la clave Zend_Navigation en el registro. Si no se establece explícitamente un contenedor ni se encuentra en el registro, el ayudante creará un contenedor Zend_Navigation vacío al llamar a $helper->getContainer().

Ejemplo 78.33. Delegar llamadas al contenedor de navegación

Los ayudantes de vista de navegación usan el método mágico __call() para delegar llamadas a métodos al contenedor de navegación que está registrado en el ayudante de vista.

$this->navigation()->addPage(array(
    'type' => 'uri',
    'label' => 'New page'));

La llamada anterior añadirá una página al contenedor en el ayudante Navigation.


78.4.1.18.1. Traducción de etiquetas y títulos

Los ayudantes de navegación admiten la traducción de etiquetas y títulos de página. Puede establecer un traductor de tipo Zend_Translate o Zend_Translate_Adapter en el ayudante usando $helper->setTranslator($translator), o como con otros componentes habilitados para I18n; añadiendo el traductor a el registro usando la clave Zend_Translate.

Si desea deshabilitar la traducción, use $helper->setUseTranslator(false).

El ayudante proxy inyectará su propio traductor al ayudante al que delega si el ayudante delegado aún no tiene un traductor.

[Note] Nota

No hay traducción en el ayudante sitemap, ya que no hay etiquetas ni títulos de página involucrados en un sitemap XML.

78.4.1.18.2. Integración con ACL

Todos los ayudantes de vista de navegación admiten ACL de forma inherente a partir de la clase Zend_View_Helper_Navigation_HelperAbstract. Se puede asignar un objeto Zend_Acl a una instancia de ayudante con $helper->setAcl($acl), y un rol con $helper->setRole('member') o $helper->setRole(new Zend_Acl_Role('member')). Si se usa ACL en el ayudante, el rol en el ayudante debe estar permitido por el ACL para acceder al resource de una página y/o tener el privilege de la página para que la página se incluya al renderizar.

Si una página no es aceptada por ACL, cualquier página descendiente también se excluirá de la renderización.

El ayudante proxy inyectará su propio ACL y rol al ayudante al que delega si el ayudante delegado aún no tiene ninguno.

Los ejemplos a continuación muestran cómo ACL afecta a la renderización.

78.4.1.18.3. Configuración de navegación usada en los ejemplos

Este ejemplo muestra la configuración de un contenedor de navegación para una empresa de software ficticia.

Notas sobre la configuración:

  • El dominio del sitio es www.example.com.

  • Las propiedades de página interesantes están marcadas con un comentario.

  • A menos que se indique lo contrario en otros ejemplos, el usuario está solicitando la URL http://www.example.com/products/server/faq/, que se traduce a la página etiquetada FAQ bajo Foo Server.

  • La configuración asumida de ACL y del enrutador se muestra debajo de la configuración del contenedor.

/*
 * Navigation container (config/array)

 * Each element in the array will be passed to
 * Zend_Navigation_Page::factory() when constructing
 * the navigation container below.
 */
$pages = array(
    array(
        'label'      => 'Home',
        'title'      => 'Go Home',
        'module'     => 'default',
        'controller' => 'index',
        'action'     => 'index',
        'order'      => -100 // make sure home is the first page
    ),
    array(
        'label'      => 'Special offer this week only!',
        'module'     => 'store',
        'controller' => 'offer',
        'action'     => 'amazing',
        'visible'    => false // not visible
    ),
    array(
        'label'      => 'Products',
        'module'     => 'products',
        'controller' => 'index',
        'action'     => 'index',
        'pages'      => array(
            array(
                'label'      => 'Foo Server',
                'module'     => 'products',
                'controller' => 'server',
                'action'     => 'index',
                'pages'      => array(
                    array(
                        'label'      => 'FAQ',
                        'module'     => 'products',
                        'controller' => 'server',
                        'action'     => 'faq',
                        'rel'        => array(
                            'canonical' => 'http://www.example.com/?page=faq',
                            'alternate' => array(
                                'module'     => 'products',
                                'controller' => 'server',
                                'action'     => 'faq',
                                'params'     => array('format' => 'xml')
                            )
                        )
                    ),
                    array(
                        'label'      => 'Editions',
                        'module'     => 'products',
                        'controller' => 'server',
                        'action'     => 'editions'
                    ),
                    array(
                        'label'      => 'System Requirements',
                        'module'     => 'products',
                        'controller' => 'server',
                        'action'     => 'requirements'
                    )
                )
            ),
            array(
                'label'      => 'Foo Studio',
                'module'     => 'products',
                'controller' => 'studio',
                'action'     => 'index',
                'pages'      => array(
                    array(
                        'label'      => 'Customer Stories',
                        'module'     => 'products',
                        'controller' => 'studio',
                        'action'     => 'customers'
                    ),
                    array(
                        'label'      => 'Support',
                        'module'     => 'prodcts',
                        'controller' => 'studio',
                        'action'     => 'support'
                    )
                )
            )
        )
    ),
    array(
        'label'      => 'Company',
        'title'      => 'About us',
        'module'     => 'company',
        'controller' => 'about',
        'action'     => 'index',
        'pages'      => array(
            array(
                'label'      => 'Investor Relations',
                'module'     => 'company',
                'controller' => 'about',
                'action'     => 'investors'
            ),
            array(
                'label'      => 'News',
                'class'      => 'rss', // class
                'module'     => 'company',
                'controller' => 'news',
                'action'     => 'index',
                'pages'      => array(
                    array(
                        'label'      => 'Press Releases',
                        'module'     => 'company',
                        'controller' => 'news',
                        'action'     => 'press'
                    ),
                    array(
                        'label'      => 'Archive',
                        'route'      => 'archive', // route
                        'module'     => 'company',
                        'controller' => 'news',
                        'action'     => 'archive'
                    )
                )
            )
        )
    ),
    array(
        'label'      => 'Community',
        'module'     => 'community',
        'controller' => 'index',
        'action'     => 'index',
        'pages'      => array(
            array(
                'label'      => 'My Account',
                'module'     => 'community',
                'controller' => 'account',
                'action'     => 'index',
                'resource'   => 'mvc:community.account' // resource
            ),
            array(
                'label' => 'Forums',
                'uri'   => 'http://forums.example.com/',
                'class' => 'external' // class
            )
        )
    ),
    array(
        'label'      => 'Administration',
        'module'     => 'admin',
        'controller' => 'index',
        'action'     => 'index',
        'resource'   => 'mvc:admin', // resource
        'pages'      => array(
            array(
                'label'      => 'Write new article',
                'module'     => 'admin',
                'controller' => 'post',
                'aciton'     => 'write'
            )
        )
    )
);

// Create container from array
$container = new Zend_Navigation($pages);

// Store the container in the proxy helper:
$view->getHelper('navigation')->setContainer($container);

// ...or simply:
$view->navigation($container);

// ...or store it in the reigstry:
Zend_Registry::set('Zend_Navigation', $container);

Además del contenedor anterior, se asume la siguiente configuración:

// Setup router (default routes and 'archive' route):
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter();
$router->addDefaultRoutes();
$router->addRoute(
    'archive',
    new Zend_Controller_Router_Route(
        '/archive/:year',
        array(
            'module'     => 'company',
            'controller' => 'news',
            'action'     => 'archive',
            'year'       => (int) date('Y') - 1
        ),
        array('year' => '\d+')
    )
);

// Setup ACL:
$acl = new Zend_Acl();
$acl->addRole(new Zend_Acl_Role('member'));
$acl->addRole(new Zend_Acl_Role('admin'));
$acl->add(new Zend_Acl_Resource('mvc:admin'));
$acl->add(new Zend_Acl_Resource('mvc:community.account'));
$acl->allow('member', 'mvc:community.account');
$acl->allow('admin', null);

// Store ACL and role in the proxy helper:
$view->navigation()->setAcl($acl)->setRole('member');

// ...or set default ACL and role statically:
Zend_View_Helper_Navigation_HelperAbstract::setDefaultAcl($acl);
Zend_View_Helper_Navigation_HelperAbstract::setDefaultRole('member');
78.4.1.18.4. Ayudante Breadcrumbs

Las migas de pan (breadcrumbs) se usan para indicar en qué parte de un sitemap está navegando actualmente un usuario, y típicamente se renderizan así: "Está aquí: Home > Products > FantasticProduct 1.0". El ayudante breadcrumbs sigue las directrices del Breadcrumbs Pattern - Yahoo! Design Pattern Library, y permite una personalización sencilla (profundidad mínima/máxima, indentación, separador, y si el último elemento debe enlazarse), o renderizar usando un script de vista parcial.

El ayudante Breadcrumbs funciona así: encuentra la página activa más profunda en un contenedor de navegación, y renderiza una ruta ascendente hacia la raíz. Para páginas MVC, la "actividad" de una página se determina inspeccionando el objeto request, tal como se indica en la sección sobre Zend_Navigation_Page_Mvc.

El ayudante establece la propiedad minDepth en 1 por defecto, lo que significa que las migas de pan no se renderizarán si la página activa más profunda es una página raíz. Si se especifica maxDepth, el ayudante dejará de renderizar cuando esté en la profundidad especificada (p. ej. detenerse en el nivel 2 aunque la página activa más profunda esté en el nivel 3).

Métodos en el ayudante breadcrumbs:

  • {get|set}Separator() obtiene/establece la cadena separadora que se usa entre las migas de pan. Por defecto es ' &gt; '.

  • {get|set}LinkLast() obtiene/establece si la última miga de pan debe renderizarse como un enlace o no. Por defecto es FALSE.

  • {get|set}Partial() obtiene/establece un script de vista parcial que debe usarse para renderizar las migas de pan. Si se establece un script de vista parcial, el método render() del ayudante usará el método renderPartial(). Si no se establece ningún parcial, se usa el método renderStraight(). El ayudante espera que el parcial sea un String o un Array con dos elementos. Si el parcial es un String, denota el nombre del script parcial a usar. Si es un Array, el primer elemento se usará como el nombre del script de vista parcial, y el segundo elemento es el módulo donde se encuentra el script.

  • renderStraight() es el método de renderización por defecto.

  • renderPartial() se usa para renderizar usando un script de vista parcial.

Ejemplo 78.34. Renderizar migas de pan

Este ejemplo muestra cómo renderizar migas de pan con la configuración por defecto.

In a view script or layout:
<?php echo $this->navigation()->breadcrumbs(); ?>

The two calls above take advantage of the magic __toString() method,
and are equivalent to:
<?php echo $this->navigation()->breadcrumbs()->render(); ?>

Output:
<a href="/products">Products</a> &gt; <a href="/products/server">Foo Server</a> &gt; FAQ

Ejemplo 78.35. Especificar indentación

Este ejemplo muestra cómo renderizar migas de pan con indentación inicial.

Rendering with 8 spaces indentation:
<?php echo $this->navigation()->breadcrumbs()->setIndent(8);?>

Output:
        <a href="/products">Products</a> &gt; <a href="/products/server">Foo Server</a> &gt; FAQ

Ejemplo 78.36. Personalizar la salida de las migas de pan

Este ejemplo muestra cómo personalizar la salida de las migas de pan especificando varias opciones.

In a view script or layout:

<?php
echo $this->navigation()
          ->breadcrumbs()
          ->setLinkLast(true)                   // link last page
          ->setMaxDepth(1)                      // stop at level 1
          ->setSeparator(' &#9654;' . PHP_EOL); // cool separator with newline
?>

Output:
<a href="/products">Products</a> &#9654;
<a href="/products/server">Foo Server</a>

/////////////////////////////////////////////////////

Setting minimum depth required to render breadcrumbs:

<?php
$this->navigation()->breadcrumbs()->setMinDepth(10);
echo $this->navigation()->breadcrumbs();
?>

Output:
Nothing, because the deepest active page is not at level 10 or deeper.

Ejemplo 78.37. Renderizar migas de pan usando un script de vista parcial

Este ejemplo muestra cómo renderizar migas de pan personalizadas usando un script de vista parcial. Al llamar a setPartial(), puede especificar un script de vista parcial que se usará al llamar a render(). Cuando se especifica un parcial, se llamará al método renderPartial(). Este método encontrará la página activa más profunda y pasará un array de páginas que llevan a la página activa al script de vista parcial.

En un layout:

$partial = ;
echo $this->navigation()->breadcrumbs()
                        ->setPartial(array('breadcrumbs.phtml', 'default'));

Contenido de application/modules/default/views/breadcrumbs.phtml:

echo implode(', ', array_map(
        function ($a) { return $a->getLabel(); },
        $this->pages));

Salida:

Products, Foo Server, FAQ

78.4.1.18.5. Ayudante Links

El ayudante links se usa para renderizar elementos LINK HTML. Los enlaces se usan para describir relaciones de documento de la página actualmente activa. Lea más sobre enlaces y tipos de enlace en Document relationships: the LINK element (HTML4 W3C Rec.) y Link types (HTML4 W3C Rec.) en la Recomendación W3C de HTML4.

Hay dos tipos de relaciones; hacia adelante y hacia atrás, indicadas por las palabras clave 'rel' y 'rev'. La mayoría de los métodos del ayudante tomarán un parámetro $rel, que debe ser ya sea 'rel' o 'rev'. La mayoría de los métodos también toman un parámetro $type, que se usa para especificar el tipo de enlace (p. ej. alternate, start, next, prev, chapter, etc).

Las relaciones pueden añadirse a los objetos de página manualmente, o encontrarse recorriendo el contenedor registrado en el ayudante. El método findRelation($page, $rel, $type) primero intentará encontrar el $rel dado de $type a partir de la $page llamando a $page->findRel($type) o $page->findRel($type). Si la $page tiene una relación que se puede convertir a una instancia de página, se usará esa relación. Si la instancia $page no tiene el $type especificado, el ayudante buscará un método en el ayudante llamado search$rel$type (p. ej. searchRelNext() o searchRevAlternate()). Si tal método existe, se usará para determinar la relación de $page recorriendo el contenedor.

No todas las relaciones pueden determinarse recorriendo el contenedor. Estas son las relaciones que se encontrarán mediante búsqueda:

  • searchRelStart(), relación 'start' hacia adelante: la primera página en el contenedor.

  • searchRelNext(), relación 'next' hacia adelante; encuentra la siguiente página en el contenedor, es decir, la página después de la página activa.

  • searchRelPrev(), relación 'prev' hacia adelante; encuentra la página anterior, es decir, la página antes de la página activa.

  • searchRelChapter(), relaciones 'chapter' hacia adelante; encuentra todas las páginas en el nivel 0 excepto la relación 'start' o la página activa si está en el nivel 0.

  • searchRelSection(), relaciones 'section' hacia adelante; encuentra todas las páginas hijas de la página activa si la página activa está en el nivel 0 (un 'chapter').

  • searchRelSubsection(), relaciones 'subsection' hacia adelante; encuentra todas las páginas hijas de la página activa si las páginas activas están en el nivel 1 (una 'section').

  • searchRevSection(), relación 'section' hacia atrás; encuentra el padre de la página activa si la página activa está en el nivel 1 (una 'section').

  • searchRevSubsection(), relación 'subsection' hacia atrás; encuentra el padre de la página activa si la página activa está en el nivel 2 (una 'subsection').

[Note] Nota

Al buscar relaciones en la instancia de página ($page->getRel($type) o $page->getRev($type)), el ayudante acepta valores de tipo String, Array, Zend_Config, o Zend_Navigation_Page. Si se encuentra una cadena, se convertirá a un Zend_Navigation_Page_Uri. Si se encuentra un array o un config, se convertirá en una o varias instancias de página. Si la primera clave del array/config es numérica, se considerará que contiene varias páginas, y cada elemento se pasará a la fábrica de páginas. Si la primera clave no es numérica, el array/config se pasará directamente a la fábrica de páginas, y se devolverá una única página.

El ayudante también admite métodos mágicos para encontrar relaciones. Por ejemplo, para encontrar relaciones alternate hacia adelante, llame a $helper->findRelAlternate($page), y para encontrar relaciones section hacia atrás, llame a $helper->findRevSection($page). Esas llamadas corresponden a $helper->findRelation($page, 'rel', 'alternate'); y $helper->findRelation($page, 'rev', 'section'); respectivamente.

Para personalizar qué relaciones deben renderizarse, el ayudante usa una marca de renderización. La marca de renderización es un valor entero, y se usará en una operación and a nivel de bits (&) contra las constantes de renderización del ayudante para determinar si la relación que pertenece a la constante de renderización debe renderizarse.

Vea el ejemplo a continuación para más información.

  • Zend_View_Helper_Navigation_Links::RENDER_ALTERNATE

  • Zend_View_Helper_Navigation_Links::RENDER_STYLESHEET

  • Zend_View_Helper_Navigation_Links::RENDER_START

  • Zend_View_Helper_Navigation_Links::RENDER_NEXT

  • Zend_View_Helper_Navigation_Links::RENDER_PREV

  • Zend_View_Helper_Navigation_Links::RENDER_CONTENTS

  • Zend_View_Helper_Navigation_Links::RENDER_INDEX

  • Zend_View_Helper_Navigation_Links::RENDER_GLOSSARY

  • Zend_View_Helper_Navigation_Links::RENDER_COPYRIGHT

  • Zend_View_Helper_Navigation_Links::RENDER_CHAPTER

  • Zend_View_Helper_Navigation_Links::RENDER_SECTION

  • Zend_View_Helper_Navigation_Links::RENDER_SUBSECTION

  • Zend_View_Helper_Navigation_Links::RENDER_APPENDIX

  • Zend_View_Helper_Navigation_Links::RENDER_HELP

  • Zend_View_Helper_Navigation_Links::RENDER_BOOKMARK

  • Zend_View_Helper_Navigation_Links::RENDER_CUSTOM

  • Zend_View_Helper_Navigation_Links::RENDER_ALL

Las constantes desde RENDER_ALTERNATE hasta RENDER_BOOKMARK denotan tipos de enlace HTML estándar. RENDER_CUSTOM denota relaciones no estándar especificadas en las páginas. RENDER_ALL denota relaciones estándar y no estándar.

Métodos en el ayudante links:

  • {get|set}RenderFlag() obtiene/establece la marca de renderización. Por defecto es RENDER_ALL. Vea los ejemplos a continuación sobre cómo establecer la marca de renderización.

  • findAllRelations() encuentra todas las relaciones de todos los tipos para una página dada.

  • findRelation() encuentra todas las relaciones de un tipo dado a partir de una página dada.

  • searchRel{Start|Next|Prev|Chapter|Section|Subsection}() recorre un contenedor para encontrar relaciones hacia adelante a la página de inicio, la siguiente página, la página anterior, capítulos, secciones y subsecciones.

  • searchRev{Section|Subsection}() recorre un contenedor para encontrar relaciones hacia atrás a secciones o subsecciones.

  • renderLink() renderiza un único elemento link.

Ejemplo 78.38. Especificar relaciones en páginas

Este ejemplo muestra cómo especificar relaciones en páginas.

$container = new Zend_Navigation(array(
    array(
        'label' => 'Relations using strings',
        'rel'   => array(
            'alternate' => 'http://www.example.org/'
        ),
        'rev'   => array(
            'alternate' => 'http://www.example.net/'
        )
    ),
    array(
        'label' => 'Relations using arrays',
        'rel'   => array(
            'alternate' => array(
                'label' => 'Example.org',
                'uri'   => 'http://www.example.org/'
            )
        )
    ),
    array(
        'label' => 'Relations using configs',
        'rel'   => array(
            'alternate' => new Zend_Config(array(
                'label' => 'Example.org',
                'uri'   => 'http://www.example.org/'
            ))
        )
    ),
    array(
        'label' => 'Relations using pages instance',
        'rel'   => array(
            'alternate' => Zend_Navigation_Page::factory(array(
                'label' => 'Example.org',
                'uri'   => 'http://www.example.org/'
            ))
        )
    )
));

Ejemplo 78.39. Renderización por defecto de enlaces

Este ejemplo muestra cómo renderizar un menú a partir de un contenedor registrado/encontrado en el ayudante de vista.

In a view script or layout:
<?php echo $this->view->navigation()->links(); ?>

Output:
<link rel="alternate" href="/products/server/faq/format/xml">
<link rel="start" href="/" title="Home">
<link rel="next" href="/products/server/editions" title="Editions">
<link rel="prev" href="/products/server" title="Foo Server">
<link rel="chapter" href="/products" title="Products">
<link rel="chapter" href="/company/about" title="Company">
<link rel="chapter" href="/community" title="Community">
<link rel="canonical" href="http://www.example.com/?page=server-faq">
<link rev="subsection" href="/products/server" title="Foo Server">

Ejemplo 78.40. Especificar qué relaciones renderizar

Este ejemplo muestra cómo especificar qué relaciones encontrar y renderizar.

Render only start, next, and prev:
$helper->setRenderFlag(Zend_View_Helper_Navigation_Links::RENDER_START |
                       Zend_View_Helper_Navigation_Links::RENDER_NEXT |
                       Zend_View_Helper_Navigation_Links::RENDER_PREV);

Output:
<link rel="start" href="/" title="Home">
<link rel="next" href="/products/server/editions" title="Editions">
<link rel="prev" href="/products/server" title="Foo Server">
Render only native link types:
$helper->setRenderFlag(Zend_View_Helper_Navigation_Links::RENDER_ALL ^
                       Zend_View_Helper_Navigation_Links::RENDER_CUSTOM);

Output:
<link rel="alternate" href="/products/server/faq/format/xml">
<link rel="start" href="/" title="Home">
<link rel="next" href="/products/server/editions" title="Editions">
<link rel="prev" href="/products/server" title="Foo Server">
<link rel="chapter" href="/products" title="Products">
<link rel="chapter" href="/company/about" title="Company">
<link rel="chapter" href="/community" title="Community">
<link rev="subsection" href="/products/server" title="Foo Server">
Render all but chapter:
$helper->setRenderFlag(Zend_View_Helper_Navigation_Links::RENDER_ALL ^
                       Zend_View_Helper_Navigation_Links::RENDER_CHAPTER);

Output:
<link rel="alternate" href="/products/server/faq/format/xml">
<link rel="start" href="/" title="Home">
<link rel="next" href="/products/server/editions" title="Editions">
<link rel="prev" href="/products/server" title="Foo Server">
<link rel="canonical" href="http://www.example.com/?page=server-faq">
<link rev="subsection" href="/products/server" title="Foo Server">

78.4.1.18.6. Ayudante Menu

El ayudante Menu se usa para renderizar menús a partir de contenedores de navegación. Por defecto, el menú se renderizará usando etiquetas HTML UL y LI, pero el ayudante también permite usar un script de vista parcial.

Métodos en el ayudante Menu:

  • {get|set}UlClass() obtiene/establece la clase CSS usada en renderMenu().

  • {get|set}ActiveClass() obtiene/establece la clase CSS para los elementos activos al renderizar.

  • {get|set}OnlyActiveBranch() obtiene/establece una marca que especifica si solo se debe renderizar la rama activa de un contenedor.

  • {get|set}ExpandSiblingNodesOfActiveBranch() obtiene/establece una marca que especifica si los nodos hermanos de todos los nodos en la rama activa también deben expandirse y renderizarse.

  • {get|set}RenderParents() obtiene/establece una marca que especifica si los padres deben renderizarse cuando solo se renderiza la rama activa de un contenedor. Si se establece en FALSE, solo se renderizará el menú activo más profundo.

  • {get|set}Partial() obtiene/establece un script de vista parcial que debe usarse para renderizar el menú. Si se establece un script de vista parcial, el método render() del ayudante usará el método renderPartial(). Si no se establece ningún parcial, se usa el método renderMenu(). El ayudante espera que el parcial sea un String o un Array con dos elementos. Si el parcial es un String, denota el nombre del script parcial a usar. Si es un Array, el primer elemento se usará como el nombre del script de vista parcial, y el segundo elemento es el módulo donde se encuentra el script.

  • htmlify() sobrescribe el método de la clase abstracta para devolver elementos span si la página no tiene href.

  • renderMenu($container = null, $options = array()) es el método de renderización por defecto, y renderizará un contenedor como una lista UL HTML.

    Si no se proporciona $container, se renderizará el contenedor registrado en el ayudante.

    $options se usa para sobrescribir opciones especificadas temporalmente sin restablecer los valores en la instancia del ayudante. Es un array asociativo donde cada clave corresponde a una opción en el ayudante.

    Opciones reconocidas:

    • indent; indentación. Espera un valor String o un int.

    • minDepth; profundidad mínima. Espera un int o NULL (sin profundidad mínima).

    • maxDepth; profundidad máxima. Espera un int o NULL (sin profundidad máxima).

    • ulClass; clase CSS para el elemento ul. Espera un String.

    • activeClass; clase CSS para los elementos activos al renderizar. Espera un String.

    • onlyActiveBranch; si solo debe renderizarse la rama activa. Espera un valor Boolean.

    • expandSiblingNodesOfActiveBranch; si los nodos hermanos de los nodos en la rama activa deben expandirse y renderizarse. Espera un valor Boolean.

    • renderParents; si los padres deben renderizarse si solo se renderiza la rama activa. Espera un valor Boolean.

    Si no se proporciona una opción, se usará el valor establecido en el ayudante.

  • renderPartial() se usa para renderizar el menú usando un script de vista parcial.

  • renderSubMenu() renderiza el nivel de menú más profundo de la rama activa de un contenedor.

Ejemplo 78.41. Renderizar un menú

Este ejemplo muestra cómo renderizar un menú a partir de un contenedor registrado/encontrado en el ayudante de vista. Observe cómo se filtran las páginas según la visibilidad y ACL.

In a view script or layout:
<?php echo $this->navigation()->menu()->render() ?>

Or simply:
<?php echo $this->navigation()->menu() ?>

Output:
<ul class="navigation">
    <li>
        <a title="Go Home" href="/">Home</a>
    </li>
    <li class="active">
        <a href="/products">Products</a>
        <ul>
            <li class="active">
                <a href="/products/server">Foo Server</a>
                <ul>
                    <li class="active">
                        <a href="/products/server/faq">FAQ</a>
                    </li>
                    <li>
                        <a href="/products/server/editions">Editions</a>
                    </li>
                    <li>
                        <a href="/products/server/requirements">System Requirements</a>
                    </li>
                </ul>
            </li>
            <li>
                <a href="/products/studio">Foo Studio</a>
                <ul>
                    <li>
                        <a href="/products/studio/customers">Customer Stories</a>
                    </li>
                    <li>
                        <a href="/prodcts/studio/support">Support</a>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
    <li>
        <a title="About us" href="/company/about">Company</a>
        <ul>
            <li>
                <a href="/company/about/investors">Investor Relations</a>
            </li>
            <li>
                <a class="rss" href="/company/news">News</a>
                <ul>
                    <li>
                        <a href="/company/news/press">Press Releases</a>
                    </li>
                    <li>
                        <a href="/archive">Archive</a>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
    <li>
        <a href="/community">Community</a>
        <ul>
            <li>
                <a href="/community/account">My Account</a>
            </li>
            <li>
                <a class="external" href="http://forums.example.com/">Forums</a>
            </li>
        </ul>
    </li>
</ul>

Ejemplo 78.42. Llamar a renderMenu() directamente

Este ejemplo muestra cómo renderizar un menú que no está registrado en el ayudante de vista llamando directamente a renderMenu() y especificando algunas opciones.

<?php
// render only the 'Community' menu
$community = $this->navigation()->findOneByLabel('Community');
$options = array(
    'indent'  => 16,
    'ulClass' => 'community'
);
echo $this->navigation()
          ->menu()
          ->renderMenu($community, $options);
?>
Output:
                <ul class="community">
                    <li>
                        <a href="/community/account">My Account</a>
                    </li>
                    <li>
                        <a class="external" href="http://forums.example.com/">Forums</a>
                    </li>
                </ul>

Ejemplo 78.43. Renderizar el menú activo más profundo

Este ejemplo muestra cómo renderSubMenu() renderizará el submenú más profundo de la rama activa.

Llamar a renderSubMenu($container, $ulClass, $indent) es equivalente a llamar a renderMenu($container, $options) con las siguientes opciones:

array(
    'ulClass'          => $ulClass,
    'indent'           => $indent,
    'minDepth'         => null,
    'maxDepth'         => null,
    'onlyActiveBranch' => true,
    'renderParents'    => false
);
<?php
echo $this->navigation()
          ->menu()
          ->renderSubMenu(null, 'sidebar', 4);
?>

The output will be the same if 'FAQ' or 'Foo Server' is active:
    <ul class="sidebar">
        <li class="active">
            <a href="/products/server/faq">FAQ</a>
        </li>
        <li>
            <a href="/products/server/editions">Editions</a>
        </li>
        <li>
            <a href="/products/server/requirements">System Requirements</a>
        </li>
    </ul>

Ejemplo 78.44. Renderizar un menú con profundidad máxima

<?php
echo $this->navigation()
          ->menu()
          ->setMaxDepth(1);
?>

Output:
<ul class="navigation">
    <li>
        <a title="Go Home" href="/">Home</a>
    </li>
    <li class="active">
        <a href="/products">Products</a>
        <ul>
            <li class="active">
                <a href="/products/server">Foo Server</a>
            </li>
            <li>
                <a href="/products/studio">Foo Studio</a>
            </li>
        </ul>
    </li>
    <li>
        <a title="About us" href="/company/about">Company</a>
        <ul>
            <li>
                <a href="/company/about/investors">Investor Relations</a>
            </li>
            <li>
                <a class="rss" href="/company/news">News</a>
            </li>
        </ul>
    </li>
    <li>
        <a href="/community">Community</a>
        <ul>
            <li>
                <a href="/community/account">My Account</a>
            </li>
            <li>
                <a class="external" href="http://forums.example.com/">Forums</a>
            </li>
        </ul>
    </li>
</ul>

Ejemplo 78.45. Renderizar un menú con profundidad mínima

<?php
echo $this->navigation()
          ->menu()
          ->setMinDepth(1);
?>

Output:
<ul class="navigation">
    <li class="active">
        <a href="/products/server">Foo Server</a>
        <ul>
            <li class="active">
                <a href="/products/server/faq">FAQ</a>
            </li>
            <li>
                <a href="/products/server/editions">Editions</a>
            </li>
            <li>
                <a href="/products/server/requirements">System Requirements</a>
            </li>
        </ul>
    </li>
    <li>
        <a href="/products/studio">Foo Studio</a>
        <ul>
            <li>
                <a href="/products/studio/customers">Customer Stories</a>
            </li>
            <li>
                <a href="/prodcts/studio/support">Support</a>
            </li>
        </ul>
    </li>
    <li>
        <a href="/company/about/investors">Investor Relations</a>
    </li>
    <li>
        <a class="rss" href="/company/news">News</a>
        <ul>
            <li>
                <a href="/company/news/press">Press Releases</a>
            </li>
            <li>
                <a href="/archive">Archive</a>
            </li>
        </ul>
    </li>
    <li>
        <a href="/community/account">My Account</a>
    </li>
    <li>
        <a class="external" href="http://forums.example.com/">Forums</a>
    </li>
</ul>

Ejemplo 78.46. Renderizar solo la rama activa de un menú

<?php
echo $this->navigation()
          ->menu()
          ->setOnlyActiveBranch(true);
?>

Output:
<ul class="navigation">
    <li class="active">
        <a href="/products">Products</a>
        <ul>
            <li class="active">
                <a href="/products/server">Foo Server</a>
                <ul>
                    <li class="active">
                        <a href="/products/server/faq">FAQ</a>
                    </li>
                    <li>
                        <a href="/products/server/editions">Editions</a>
                    </li>
                    <li>
                        <a href="/products/server/requirements">System Requirements</a>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

Ejemplo 78.47. Renderizar solo la rama activa de un menú con profundidad mínima

<?php
echo $this->navigation()
          ->menu()
          ->setOnlyActiveBranch(true)
          ->setMinDepth(1);
?>

Output:
<ul class="navigation">
    <li class="active">
        <a href="/products/server">Foo Server</a>
        <ul>
            <li class="active">
                <a href="/products/server/faq">FAQ</a>
            </li>
            <li>
                <a href="/products/server/editions">Editions</a>
            </li>
            <li>
                <a href="/products/server/requirements">System Requirements</a>
            </li>
        </ul>
    </li>
</ul>

Ejemplo 78.48. Renderizar solo la rama activa de un menú con profundidad máxima

<?php
echo $this->navigation()
          ->menu()
          ->setOnlyActiveBranch(true)
          ->setMaxDepth(1);
?>

Output:
<ul class="navigation">
    <li class="active">
        <a href="/products">Products</a>
        <ul>
            <li class="active">
                <a href="/products/server">Foo Server</a>
            </li>
            <li>
                <a href="/products/studio">Foo Studio</a>
            </li>
        </ul>
    </li>
</ul>

Ejemplo 78.49. Renderizar solo la rama activa de un menú con profundidad máxima y sin padres

<?php
echo $this->navigation()
          ->menu()
          ->setOnlyActiveBranch(true)
          ->setRenderParents(false)
          ->setMaxDepth(1);
?>

Output:
<ul class="navigation">
    <li class="active">
        <a href="/products/server">Foo Server</a>
    </li>
    <li>
        <a href="/products/studio">Foo Studio</a>
    </li>
</ul>

Ejemplo 78.50. Renderizar un menú personalizado usando un script de vista parcial

Este ejemplo muestra cómo renderizar un menú personalizado usando un script de vista parcial. Al llamar a setPartial(), puede especificar un script de vista parcial que se usará al llamar a render(). Cuando se especifica un parcial, se llamará al método renderPartial(). Este método asignará el contenedor a la vista con la clave container.

En un layout:

$partial = array('menu.phtml', 'default');
$this->navigation()->menu()->setPartial($partial);
echo $this->navigation()->menu()->render();

En application/modules/default/views/menu.phtml:

foreach ($this->container as $page) {
    echo $this->navigation()->menu()->htmlify($page), PHP_EOL;
}

Salida:

<a title="Go Home" href="/">Home</a>
<a href="/products">Products</a>
<a title="About us" href="/company/about">Company</a>
<a href="/community">Community</a>

Ejemplo 78.51. Renderizar solo la rama activa y todos los hermanos de la rama activa

echo $this->navigation()
          ->menu()
          ->setExpandSiblingNodesOfActiveBranch(true);

Salida:

<ul class="navigation">
    <li>
        <a title="Go Home" href="/">Home</a>
    </li>
    <li class="active">
        <a href="/products">Products</a>
        <ul>
            <li class="active">
                <a href="/products/server">Foo Server</a>
                <ul>
                    <li class="active">
                        <a href="/products/server/faq">FAQ</a>
                    </li>
                    <li>
                        <a href="/products/server/editions">Editions</a>
                    </li>
                    <li>
                        <a href="/products/server/requirements">System Requirements</a>
                    </li>
                </ul>
            </li>
            <li>
                <a href="/products/studio">Foo Studio</a>
            </li>
        </ul>
    </li>
    <li>
        <a title="About us" href="/company/about">Company</a>
    </li>
    <li>
        <a href="/community">Community</a>
    </li>
</ul>

78.4.1.18.7. Ayudante Sitemap

El ayudante Sitemap se usa para generar sitemaps XML, tal como se define en el formato XML de Sitemaps. Lea más sobre Sitemaps en Wikipedia.

Por defecto, el ayudante sitemap usa validadores de sitemap para validar cada elemento que se renderiza. Esto puede deshabilitarse llamando a $helper->setUseSitemapValidators(false).

[Note] Nota

Si deshabilita los validadores de sitemap, las propiedades personalizadas (vea la tabla) no se validan en absoluto.

El ayudante sitemap también admite la validación de esquema XSD de Sitemap del sitemap generado. Esto está deshabilitado por defecto, ya que requerirá una solicitud al archivo de esquema. Puede habilitarse con $helper->setUseSchemaValidation(true).

Tabla 78.1. Elementos XML de Sitemap

Elemento Descripción
loc URL absoluta a la página. El ayudante generará una URL absoluta.
lastmod

La fecha de la última modificación del archivo, en formato W3C Datetime. Esta parte de la hora puede omitirse si se desea, y usar solo AAAA-MM-DD.

El ayudante intentará recuperar el valor lastmod de la propiedad personalizada lastmod de la página si está establecida en la página. Si el valor no es una fecha válida, se ignora.

changefreq

Con qué frecuencia es probable que cambie la página. Este valor proporciona información general a los motores de búsqueda y puede no corresponder exactamente a la frecuencia con la que rastrean la página. Los valores válidos son:

  • always

  • hourly

  • daily

  • weekly

  • monthly

  • yearly

  • never

El ayudante intentará recuperar el valor changefreq de la propiedad personalizada changefreq de la página si está establecida en la página. Si el valor no es válido, se ignora.

priority

La prioridad de esta URL en relación con otras URLs de su sitio. Los valores válidos van de 0.0 a 1.0.

El ayudante intentará recuperar el valor priority de la propiedad personalizada priority de la página si está establecida en la página. Si el valor no es válido, se ignora.


Métodos en el ayudante sitemap:

  • {get|set}FormatOutput() obtiene/establece una marca que indica si la salida XML debe formatearse. Esto corresponde a la propiedad formatOutput de la clase nativa DOMDocument. Lea más en PHP: DOMDocument - Manual. Por defecto es FALSE.

  • {get|set}UseXmlDeclaration() obtiene/establece una marca que indica si la declaración XML debe incluirse al renderizar. Por defecto es TRUE.

  • {get|set}UseSitemapValidators() obtiene/establece una marca que indica si deben usarse validadores de sitemap al generar el sitemap DOM. Por defecto es TRUE.

  • {get|set}UseSchemaValidation() obtiene/establece una marca que indica si el ayudante debe usar validación de esquema XML al generar el sitemap DOM. Por defecto es FALSE. Si es TRUE.

  • {get|set}ServerUrl() obtiene/establece la URL de servidor que se antepondrá a las URLs no absolutas en el método url(). Si no se especifica ninguna URL de servidor, la determinará el ayudante.

  • url() se usa para generar URLs absolutas a páginas.

  • getDomSitemap() genera un DOMDocument a partir de un contenedor dado.

Ejemplo 78.52. Renderizar un sitemap XML

Este ejemplo muestra cómo renderizar un sitemap XML basado en la configuración que hicimos más arriba.

// In a view script or layout:

// format output
$this->navigation()
      ->sitemap()
      ->setFormatOutput(true); // default is false

// other possible methods:
// ->setUseXmlDeclaration(false); // default is true
// ->setServerUrl('http://my.otherhost.com');
// default is to detect automatically

// print sitemap
echo $this->navigation()->sitemap();

Observe cómo las páginas que son invisibles o las páginas con roles ACL incompatibles con el ayudante de vista se filtran:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>http://www.example.com/</loc>
  </url>
  <url>
    <loc>http://www.example.com/products</loc>
  </url>
  <url>
    <loc>http://www.example.com/products/server</loc>
  </url>
  <url>
    <loc>http://www.example.com/products/server/faq</loc>
  </url>
  <url>
    <loc>http://www.example.com/products/server/editions</loc>
  </url>
  <url>
    <loc>http://www.example.com/products/server/requirements</loc>
  </url>
  <url>
    <loc>http://www.example.com/products/studio</loc>
  </url>
  <url>
    <loc>http://www.example.com/products/studio/customers</loc>
  </url>
  <url>
    <loc>http://www.example.com/prodcts/studio/support</loc>
  </url>
  <url>
    <loc>http://www.example.com/company/about</loc>
  </url>
  <url>
    <loc>http://www.example.com/company/about/investors</loc>
  </url>
  <url>
    <loc>http://www.example.com/company/news</loc>
  </url>
  <url>
    <loc>http://www.example.com/company/news/press</loc>
  </url>
  <url>
    <loc>http://www.example.com/archive</loc>
  </url>
  <url>
    <loc>http://www.example.com/community</loc>
  </url>
  <url>
    <loc>http://www.example.com/community/account</loc>
  </url>
  <url>
    <loc>http://forums.example.com/</loc>
  </url>
</urlset>

Renderice el sitemap sin ningún rol ACL (debería filtrar /community/account):

echo $this->navigation()
          ->sitemap()
          ->setFormatOutput(true)
          ->setRole();
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>http://www.example.com/</loc>
  </url>
  <url>
    <loc>http://www.example.com/products</loc>
  </url>
  <url>
    <loc>http://www.example.com/products/server</loc>
  </url>
  <url>
    <loc>http://www.example.com/products/server/faq</loc>
  </url>
  <url>
    <loc>http://www.example.com/products/server/editions</loc>
  </url>
  <url>
    <loc>http://www.example.com/products/server/requirements</loc>
  </url>
  <url>
    <loc>http://www.example.com/products/studio</loc>
  </url>
  <url>
    <loc>http://www.example.com/products/studio/customers</loc>
  </url>
  <url>
    <loc>http://www.example.com/prodcts/studio/support</loc>
  </url>
  <url>
    <loc>http://www.example.com/company/about</loc>
  </url>
  <url>
    <loc>http://www.example.com/company/about/investors</loc>
  </url>
  <url>
    <loc>http://www.example.com/company/news</loc>
  </url>
  <url>
    <loc>http://www.example.com/company/news/press</loc>
  </url>
  <url>
    <loc>http://www.example.com/archive</loc>
  </url>
  <url>
    <loc>http://www.example.com/community</loc>
  </url>
  <url>
    <loc>http://forums.example.com/</loc>
  </url>
</urlset>

Renderice el sitemap usando una profundidad máxima de 1.

echo $this->navigation()
          ->sitemap()
          ->setFormatOutput(true)
          ->setMaxDepth(1);
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>http://www.example.com/</loc>
  </url>
  <url>
    <loc>http://www.example.com/products</loc>
  </url>
  <url>
    <loc>http://www.example.com/products/server</loc>
  </url>
  <url>
    <loc>http://www.example.com/products/studio</loc>
  </url>
  <url>
    <loc>http://www.example.com/company/about</loc>
  </url>
  <url>
    <loc>http://www.example.com/company/about/investors</loc>
  </url>
  <url>
    <loc>http://www.example.com/company/news</loc>
  </url>
  <url>
    <loc>http://www.example.com/community</loc>
  </url>
  <url>
    <loc>http://www.example.com/community/account</loc>
  </url>
  <url>
    <loc>http://forums.example.com/</loc>
  </url>
</urlset>

[Note] Se usa la codificación UTF-8 por defecto

Por defecto, Zend Framework usa UTF-8 como su codificación por defecto, y, específicamente en este caso, Zend_View también. La codificación de caracteres puede establecerse de manera diferente en el propio objeto de vista usando el método setEncoding() (o el parámetro de instanciación encoding). Sin embargo, dado que Zend_View_Interface no define accesores para la codificación, es posible que si está usando una implementación de vista personalizada con el ayudante de vista Dojo, no tenga un método getEncoding(), que es lo que el ayudante de vista usa internamente para determinar el juego de caracteres en el que codificar.

Si no desea utilizar UTF-8 en tal situación, deberá implementar un método getEncoding() en su implementación de vista personalizada.

78.4.1.18.8. Ayudante Navigation

El ayudante Navigation es un ayudante proxy que reenvía llamadas a otros ayudantes de navegación. Puede considerarse un punto de entrada a todas las tareas de vista relacionadas con la navegación. Los ayudantes de navegación mencionados anteriormente están en el espacio de nombres Zend_View_Helper_Navigation, y por lo tanto requerirían que se añadiera la ruta Zend/View/Helper/Navigation como una ruta de ayudante a la vista. Con el ayudante proxy residiendo en el espacio de nombres Zend_View_Helper, siempre estará disponible, sin necesidad de añadir ninguna ruta de ayudante a la vista.

El ayudante Navigation encuentra otros ayudantes que implementan la interfaz Zend_View_Helper_Navigation_Helper, lo que significa que los ayudantes de vista personalizados también pueden ser delegados. Esto, sin embargo, requeriría que se añada la ruta del ayudante personalizado a la vista.

Al delegar a otros ayudantes, el ayudante Navigation puede inyectar su contenedor, ACL/rol, y traductor. Esto significa que no tendrá que establecer explícitamente los tres en todos los ayudantes de navegación, ni recurrir a la inyección mediante Zend_Registry o métodos estáticos.

  • findHelper() encuentra el ayudante dado, verifica que sea un ayudante de navegación, e inyecta contenedor, ACL/rol y traductor.

  • {get|set}InjectContainer() obtiene/establece una marca que indica si el contenedor debe inyectarse a los ayudantes delegados. Por defecto es TRUE.

  • {get|set}InjectAcl() obtiene/establece una marca que indica si el ACL/rol debe inyectarse a los ayudantes delegados. Por defecto es TRUE.

  • {get|set}InjectTranslator() obtiene/establece una marca que indica si el traductor debe inyectarse a los ayudantes delegados. Por defecto es TRUE.

  • {get|set}DefaultProxy() obtiene/establece el proxy por defecto. Por defecto es 'menu'.

  • render() delega al método render del proxy por defecto.

78.4.1.19. Ayudante Translate

A menudo los sitios web están disponibles en varios idiomas. Para traducir el contenido de un sitio, simplemente debería usar Zend_Translate y para integrar Zend_Translate dentro de su vista debería usar el ayudante de vista Translate.

En todos los ejemplos siguientes usamos el simple adaptador de traducción Array. Por supuesto, también puede usar cualquier instancia de Zend_Translate y también cualquier subclase de Zend_Translate_Adapter. Hay varias formas de iniciar el ayudante de vista Translate:

  • Registrado, a través de una instancia previamente registrada en Zend_Registry

  • Posteriormente, a través de la interfaz fluida

  • Directamente, iniciando la clase

Una instancia registrada de Zend_Translate es el uso preferido para este ayudante. También puede seleccionar el locale a usar simplemente antes de añadir el adaptador al registro.

[Note] Nota

Hablamos de locales en lugar de idiomas porque un idioma también puede contener una región. Por ejemplo, el inglés se habla en diferentes dialectos. Puede haber una traducción para el inglés británico y otra para el inglés estadounidense. Por lo tanto, decimos "locale" en lugar de "idioma".

Ejemplo 78.53. Instancia registrada

Para usar una instancia registrada, simplemente cree una instancia de Zend_Translate o Zend_Translate_Adapter y regístrela dentro de Zend_Registry usando Zend_Translate como su clave.

// our example adapter
$adapter = new Zend_Translate(
    array(
        'adapter' => 'array',
        'content' => array('simple' => 'einfach'),
        'locale'  => 'de'
    )
);
Zend_Registry::set('Zend_Translate', $adapter);

// within your view
echo $this->translate('simple');
// this returns 'einfach'

Si está más familiarizado con la interfaz fluida, también puede crear una instancia dentro de su vista e iniciar el ayudante posteriormente.

Ejemplo 78.54. Dentro de la vista

Para usar la interfaz fluida, cree una instancia de Zend_Translate o Zend_Translate_Adapter, llame al ayudante sin ningún parámetro, y llame al método setTranslator().

// within your view
$adapter = new Zend_Translate(
    array(
        'adapter' => 'array',
        'content' => array('simple' => 'einfach'),
        'locale'  => 'de'
    )
);
$this->translate()->setTranslator($adapter)->translate('simple');
// this returns 'einfach'

Si está usando el ayudante sin Zend_View, también puede usarlo directamente.

Ejemplo 78.55. Uso directo

// our example adapter
$adapter = new Zend_Translate(
    array(
        'adapter' => 'array',
        'content' => array('simple' => 'einfach'),
        'locale'  => 'de'
    )
);

// initiate the adapter
$translate = new Zend_View_Helper_Translate($adapter);
print $translate->translate('simple'); // this returns 'einfach'

Usaría esta forma si no está trabajando con Zend_View y necesita crear salida traducida.


Como ya se ha visto, el método translate() se usa para devolver la traducción. Simplemente llámelo con el messageid necesario de su adaptador de traducción. Pero también puede reemplazar parámetros dentro de la cadena de traducción. Por lo tanto, acepta parámetros variables de dos maneras: ya sea como una lista de parámetros, o como un array de parámetros. Como ejemplos:

Ejemplo 78.56. Parámetro único

Para usar un único parámetro, simplemente añádalo al método.

// within your view
$date = "Monday";
$this->translate("Today is %1\$s", $date);
// could return 'Heute ist Monday'

[Note] Nota

Tenga en cuenta que si está usando parámetros que también son texto, es posible que también necesite traducir estos parámetros.

Ejemplo 78.57. Lista de parámetros

O use una lista de parámetros y añádala al método.

// within your view
$date = "Monday";
$month = "April";
$time = "11:20:55";
$this->translate("Today is %1\$s in %2\$s. Actual time: %3\$s",
                 $date,
                 $month,
                 $time);
// Could return 'Heute ist Monday in April. Aktuelle Zeit: 11:20:55'

Ejemplo 78.58. Array de parámetros

O use un array de parámetros y añádalo al método.

// within your view
$date = array("Monday", "April", "11:20:55");
$this->translate("Today is %1\$s in %2\$s. Actual time: %3\$s", $date);
// Could return 'Heute ist Monday in April. Aktuelle Zeit: 11:20:55'

A veces es necesario cambiar el locale de la traducción. Esto puede hacerse ya sea dinámicamente por traducción o estáticamente para todas las traducciones siguientes. Y puede usarlo tanto con una lista de parámetros como con un array de parámetros. En ambos casos, el locale debe darse como el último parámetro único.

Ejemplo 78.59. Cambiar el locale dinámicamente

// within your view
$date = array("Monday", "April", "11:20:55");
$this->translate("Today is %1\$s in %2\$s. Actual time: %3\$s", $date, 'it');

Este ejemplo devuelve la traducción italiana para el messageid. Pero solo se usará una vez. La siguiente traducción usará el locale del adaptador. Normalmente establecerá el locale deseado dentro del adaptador de traducción antes de añadirlo al registro. Pero también puede establecer el locale desde dentro del ayudante:

Ejemplo 78.60. Cambiar el locale estáticamente

// within your view
$date = array("Monday", "April", "11:20:55");
$this->translate()->setLocale('it');
$this->translate("Today is %1\$s in %2\$s. Actual time: %3\$s", $date);

El ejemplo anterior establece 'it' como el nuevo locale por defecto que se usará para todas las traducciones futuras.

Por supuesto, también hay un método getLocale() para obtener el locale actualmente establecido.

Ejemplo 78.61. Obtener el locale actualmente establecido

// within your view
$date = array("Monday", "April", "11:20:55");

// returns 'de' as set default locale from our above examples
$this->translate()->getLocale();

$this->translate()->setLocale('it');
$this->translate("Today is %1\$s in %2\$s. Actual time: %3\$s", $date);

// returns 'it' as new set default locale
$this->translate()->getLocale();

78.4.1.20. Ayudante de vista UserAgent

78.4.1.20.1. Resumen

Este ayudante de vista proporciona la capacidad de inyectar y posteriormente recuperar una instancia de Zend_Http_UserAgent para su uso en la lógica de visualización condicional basada en las capacidades del dispositivo.

78.4.1.20.2. Inicio rápido

En la mayoría de los casos, simplemente puede recuperar el User-Agent y el dispositivo relacionado llamando al ayudante. Si el UserAgent se configuró en el bootstrap, esa instancia ya estará inyectada en el ayudante; de lo contrario, instanciará una por usted.

<?php if ($this->userAgent()->getDevice()->hasFlash()): ?>
    <object ...></object>
<?php endif ?>

Si inicializa el objeto UserAgent manualmente, aún puede inyectarlo en el ayudante, de una de dos maneras.

// Pull the helper from the view, and inject:
$helper = $view->getHelper('userAgent');
$helper->setUserAgent($userAgent);

// Pass the UserAgent to the helper:
$view->userAgent($userAgent);
78.4.1.20.3. Métodos disponibles
userAgent(Zend_Http_UserAgent $userAgent = null);

Use este método para establecer o recuperar la instancia de UserAgent. Pasar una instancia la establecerá; no pasar argumentos la recuperará. Si no se ha registrado una instancia previa, se cargará de forma diferida usando valores por defecto.

setUserAgent(Zend_Http_UserAgent $userAgent);

Si tiene una instancia del ayudante -- por ejemplo, llamando al método getHelper() del objeto de vista -- puede usar este método para establecer la instancia de UserAgent.

getUserAgent();

Recupera la instancia de UserAgent; si no hay ninguna registrada, cargará una de forma diferida usando valores por defecto.

78.4.2. Rutas de ayudantes

Al igual que con los scripts de vista, su controlador puede especificar una pila de rutas para que Zend_View busque clases ayudantes. Por defecto, Zend_View busca en "Zend/View/Helper/*" las clases ayudantes. Puede indicarle a Zend_View que busque en otras ubicaciones usando los métodos setHelperPath() y addHelperPath(). Además, puede indicar un prefijo de clase para usar con los ayudantes en la ruta proporcionada, para permitir asignar espacios de nombres a sus clases ayudantes. Por defecto, si no se proporciona ningún prefijo de clase, se asume 'Zend_View_Helper_'.

$view = new Zend_View();

// Set path to /path/to/more/helpers, with prefix 'My_View_Helper'
$view->setHelperPath('/path/to/more/helpers', 'My_View_Helper');

De hecho, puede "apilar" rutas usando el método addHelperPath(). A medida que añade rutas a la pila, Zend_View buscará en la ruta añadida más recientemente la clase ayudante solicitada. Esto le permite añadir a (o incluso sobrescribir) la distribución inicial de ayudantes con sus propios ayudantes personalizados.

$view = new Zend_View();
// Add /path/to/some/helpers with class prefix 'My_View_Helper'
$view->addHelperPath('/path/to/some/helpers', 'My_View_Helper');
// Add /other/path/to/helpers with class prefix 'Your_View_Helper'
$view->addHelperPath('/other/path/to/helpers', 'Your_View_Helper');

// now when you call $this->helperName(), Zend_View will look first for
// "/path/to/some/helpers/HelperName" using class name
// "Your_View_Helper_HelperName", then for
// "/other/path/to/helpers/HelperName.php" using class name
// "My_View_Helper_HelperName", and finally for
// "Zend/View/Helper/HelperName.php" using class name
// "Zend_View_Helper_HelperName".

78.4.3. Escribir ayudantes personalizados

Escribir ayudantes personalizados es fácil; solo siga estas reglas:

  • Aunque no es estrictamente necesario, recomendamos implementar Zend_View_Helper_Interface o extender Zend_View_Helper_Abstract al crear sus ayudantes. Introducidos en la 1.6.0, estos simplemente definen un método setView(); sin embargo, en próximas versiones, planeamos implementar un patrón de estrategia que simplificará gran parte del esquema de nomenclatura detallado a continuación. Construir sobre estos ahora le ayudará a proteger su código de cara al futuro.

  • El nombre de la clase debe, como mínimo, terminar con el propio nombre del ayudante, usando MixedCaps. Por ejemplo, si estuviera escribiendo un ayudante llamado "specialPurpose", el nombre de la clase necesitaría ser mínimamente "SpecialPurpose". Puede, y debería, darle a la clase un prefijo, y se recomienda que use 'View_Helper' como parte de ese prefijo: "My_View_Helper_SpecialPurpose". (Necesitará pasar el prefijo, con o sin el guion bajo final, a addHelperPath() o setHelperPath()).

  • La clase debe tener un método público que coincida con el nombre del ayudante; este es el método que se llamará cuando su plantilla llame a "$this->specialPurpose()". En nuestro ejemplo del ayudante "specialPurpose", la declaración de método requerida sería "public function specialPurpose()".

  • En general, la clase no debería mostrar con echo, imprimir, ni generar salida de otra manera. En su lugar, debería devolver valores para ser impresos o mostrados con echo. Los valores devueltos deben escaparse apropiadamente.

  • La clase debe estar en un archivo nombrado según la clase del ayudante. Nuevamente usando nuestro ejemplo del ayudante "specialPurpose", el archivo debe llamarse "SpecialPurpose.php".

Coloque el archivo de la clase ayudante en algún lugar de su pila de rutas de ayudantes, y Zend_View lo cargará, instanciará, persistirá y ejecutará automáticamente por usted.

Aquí hay un ejemplo del código de nuestro ayudante SpecialPurpose:

class My_View_Helper_SpecialPurpose extends Zend_View_Helper_Abstract
{
    protected $_count = 0;
    public function specialPurpose()
    {
        $this->_count++;
        $output = "I have seen 'The Jerk' {$this->_count} time(s).";
        return htmlspecialchars($output);
    }
}

Luego, en un script de vista, puede llamar al ayudante SpecialPurpose tantas veces como desee; se instanciará una vez, y luego persistirá durante la vida de esa instancia de Zend_View.

// remember, in a view script, $this refers to the Zend_View instance.
echo $this->specialPurpose();
echo $this->specialPurpose();
echo $this->specialPurpose();

La salida se vería algo así:

I have seen 'The Jerk' 1 time(s).
I have seen 'The Jerk' 2 time(s).
I have seen 'The Jerk' 3 time(s).

A veces necesitará acceso al objeto Zend_View que hace la llamada -- por ejemplo, si necesita usar la codificación registrada, o desea renderizar otro script de vista como parte de su ayudante. Para obtener acceso al objeto de vista, su clase ayudante debería tener un método setView($view), como el siguiente:

class My_View_Helper_ScriptPath
{
    public $view;

    public function setView(Zend_View_Interface $view)
    {
        $this->view = $view;
    }

    public function scriptPath($script)
    {
        return $this->view->getScriptPath($script);
    }
}

Si su clase ayudante tiene un método setView(), se llamará cuando la clase ayudante se instancie por primera vez, y se le pasará el objeto de vista actual. Depende de usted persistir el objeto en su clase, así como determinar cómo debe accederse a él.

Si está extendiendo Zend_View_Helper_Abstract, no necesita definir este método, ya que está definido por usted.

78.4.4. Registrar ayudantes concretos

En ocasiones es conveniente instanciar un ayudante de vista, y luego registrarlo con la vista. A partir de la versión 1.10.0, esto ahora es posible usando el método registerHelper(), que espera dos argumentos: el objeto ayudante, y el nombre con el que se registrará.

$helper = new My_Helper_Foo();
// ...do some configuration or dependency injection...

$view->registerHelper($helper, 'foo');

Si el ayudante tiene un método setView(), el objeto de vista llamará a este e inyectará a sí mismo en el ayudante al registrarse.

[Note] El nombre del ayudante debe coincidir con un método

El segundo argumento de registerHelper() es el nombre del ayudante. Debe existir un nombre de método correspondiente en el ayudante; de lo contrario, Zend_View llamará a un método inexistente al invocar el ayudante, generando un error fatal de PHP.