TigerZF
🌐Español

7.3. Placeholders estándar

En la sección anterior, aprendimos sobre el helper de vista placeholder(), y cómo puede usarse para agregar contenido personalizado. En esta sección, veremos algunos de los placeholders concretos incluidos con Zend Framework, y cómo puede usarlos en su beneficio al crear layouts compuestos complejos.

La mayoría de los placeholders incluidos sirven para generar contenido para la sección <head> de su contenido de layout -- un área que normalmente no puede manipular directamente a través de sus scripts de vista de la aplicación, pero sobre la que puede querer influir. Como ejemplos: puede querer que su título contenga cierto contenido en cada página, pero contenido específico según el controlador y/o la acción; puede querer especificar archivos CSS a cargar según en qué sección de la aplicación se encuentre; puede necesitar scripts JavaScript específicos cargados en diferentes momentos; o puede querer establecer la declaración de DocType.

Zend Framework incluye implementaciones de placeholder para cada una de estas situaciones, y varias más.

7.3.1. Estableciendo el DocType

Las declaraciones de DocType son difíciles de memorizar, y a menudo esenciales de incluir en su documento para asegurar que el navegador renderice correctamente su contenido. El helper de vista doctype() le permite usar mnemónicos de cadena simples para especificar el DocType deseado; adicionalmente, otros helpers consultarán al helper doctype() para asegurar que la salida generada cumpla con el DocType solicitado.

Como ejemplo, si desea usar el DTD Strict de XHTML1, simplemente puede especificar:

$this->doctype('XHTML1_STRICT');

Entre los demás mnemónicos disponibles, encontrará estos tipos comunes:

XHTML1_STRICT

XHTML 1.0 Strict

XHTML1_TRANSITIONAL

XHTML 1.0 Transitional

HTML4_STRICT

HTML 4.01 Strict

HTML4_Loose

HTML 4.01 Loose

HTML5

HTML 5

Puede asignar el tipo y renderizar la declaración en una sola llamada:

echo $this->doctype('XHTML1_STRICT');

Sin embargo, el mejor enfoque es asignar el tipo en su bootstrap, y luego renderizarlo en su layout. Intente añadir lo siguiente a su clase bootstrap:

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    protected function _initDocType()
    {
        $this->bootstrap('View');
        $view = $this->getResource('View');
        $view->doctype('XHTML1_STRICT');
    }
}

Luego, en su script de layout, simplemente haga echo() del helper en la parte superior del archivo:

<?php echo $this->doctype() ?>
<html>
    <!-- ... -->

Esto asegurará que sus helpers de vista sensibles al DocType rendericen el marcado apropiado, que el tipo se establezca mucho antes de que se renderice el layout, y que se disponga de una única ubicación para cambiar el DocType.

7.3.2. Especificando el título de la página

A menudo, un sitio incluirá el nombre del sitio o negocio como parte del título de la página, y luego añadirá información adicional según la ubicación dentro del sitio. Como ejemplo, el sitio web zend.com incluye la cadena "Zend.com" en todas las páginas, y antepone información según la página: "Zend Server - Zend.com". Dentro de Zend Framework, el helper de vista headTitle() puede ayudar a simplificar esta tarea.

En su forma más simple, el helper headTitle() le permite agregar contenido para la etiqueta <title>; cuando lo imprime con echo, ensambla el contenido según el orden en que se añaden los segmentos. Puede controlar el orden usando prepend() y append(), y proporcionar un separador a usar entre segmentos mediante el método setSeparator().

Normalmente, debería especificar en su bootstrap cualquier segmento común a todas las páginas, de forma similar a como definimos el doctype. En este caso, definiremos un método _initPlaceholders() para operar sobre los distintos placeholders, y especificaremos un título inicial así como un separador.

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    // ...

    protected function _initPlaceholders()
    {
        $this->bootstrap('View');
        $view = $this->getResource('View');
        $view->doctype('XHTML1_STRICT');

        // Set the initial title and separator:
        $view->headTitle('My Site')
             ->setSeparator(' :: ');
    }

    // ...
}

Dentro de un script de vista, podríamos querer añadir otro segmento:

<?php $this->headTitle()->append('Some Page'); // place after other segments ?>
<?php $this->headTitle()->prepend('Some Page'); // place before ?>

En nuestro layout, simplemente haremos echo del helper headTitle():

<?php echo $this->doctype() ?>
<html>
    <?php echo $this->headTitle() ?>
    <!-- ... -->

Esto generará la siguiente salida:

<!-- If append() was used: -->
<title>My Site :: Some Page</title>

<!-- If prepend() was used: -->
<title>Some Page :: My Site</title>

7.3.3. Especificando hojas de estilo con HeadLink

Los buenos desarrolladores de CSS a menudo crearán una hoja de estilo general para los estilos de todo el sitio, y hojas de estilo individuales para secciones o páginas específicas del sitio web, y cargarán estas últimas condicionalmente para reducir la cantidad de datos que necesitan transferirse en cada petición. El placeholder headLink() hace que esta agregación condicional de hojas de estilo sea trivial dentro de su aplicación.

Para lograr esto, headLink() define una serie de métodos "virtuales" (mediante overloading) para hacer trivial el proceso. Los que nos interesan son appendStylesheet() y prependStylesheet(). Cada uno acepta hasta cuatro argumentos, $href (la ruta relativa a la hoja de estilo), $media (el tipo MIME, que por defecto es "text/css"), $conditionalStylesheet (que puede usarse para especificar una "condición" bajo la cual se evaluará la hoja de estilo), y $extras (un array asociativo de pares clave y valor, comúnmente usado para especificar una clave para "media"). En la mayoría de los casos, solo necesitará especificar el primer argumento, la ruta relativa a la hoja de estilo.

En nuestro ejemplo, asumiremos que todas las páginas necesitan cargar la hoja de estilo ubicada en "/styles/site.css" (relativa a la raíz del documento); especificaremos esto en nuestro método bootstrap _initPlaceholders().

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    // ...

    protected function _initPlaceholders()
    {
        $this->bootstrap('View');
        $view = $this->getResource('View');
        $view->doctype('XHTML1_STRICT');

        // Set the initial title and separator:
        $view->headTitle('My Site')
             ->setSeparator(' :: ');

        // Set the initial stylesheet:
        $view->headLink()->prependStylesheet('/styles/site.css');
    }

    // ...
}

Más adelante, en un controlador o en un script de vista específico de una acción, podemos añadir más hojas de estilo:

<?php $this->headLink()->appendStylesheet('/styles/user-list.css') ?>

Dentro de nuestro script de vista de layout, una vez más, simplemente hacemos echo del placeholder:

<?php echo $this->doctype() ?>
<html>
    <?php echo $this->headTitle() ?>
    <?php echo $this->headLink() ?>
    <!-- ... -->

Esto generará la siguiente salida:

<link rel="stylesheet" type="text/css" href="/styles/site.css" />
<link rel="stylesheet" type="text/css" href="/styles/user-list.css" />

7.3.4. Agregando scripts usando HeadScript

Otra táctica común para evitar tiempos de carga de página largos es cargar JavaScript solo cuando sea necesario. Dicho esto, puede necesitar varias capas de scripts: quizás una para mejorar progresivamente los menús del sitio, y otra para contenido específico de la página. En estas situaciones, el helper headScript() presenta una solución.

De forma similar al helper headLink(), headScript() ofrece la capacidad de añadir al final o al principio scripts a la colección, y luego imprimir con echo todo el conjunto. Proporciona la flexibilidad de especificar tanto los propios archivos de script a cargar, como JavaScript explícito. También tiene la opción de capturar JavaScript mediante captureStart()/captureEnd(), lo que le permite simplemente incluir en línea el JavaScript en lugar de requerir una llamada adicional a su servidor.

También como headLink(), headScript() proporciona métodos "virtuales" mediante overloading como conveniencia al especificar elementos a agregar; los métodos comunes incluyen prependFile(), appendFile(), prependScript(), y appendScript(). Los dos primeros le permiten especificar archivos que se referenciarán en el atributo $src de una etiqueta <script>; los dos últimos tomarán el contenido proporcionado y lo renderizarán como JavaScript literal dentro de una etiqueta <script>.

En este ejemplo, especificaremos que un script, "/js/site.js" necesita cargarse en cada página; actualizaremos nuestro método bootstrap _initPlaceholders() para hacer esto.

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    // ...

    protected function _initPlaceholders()
    {
        $this->bootstrap('View');
        $view = $this->getResource('View');
        $view->doctype('XHTML1_STRICT');

        // Set the initial title and separator:
        $view->headTitle('My Site')
             ->setSeparator(' :: ');

        // Set the initial stylesheet:
        $view->headLink()->prependStylesheet('/styles/site.css');

        // Set the initial JS to load:
        $view->headScript()->prependFile('/js/site.js');
    }

    // ...
}

Dentro de un script de vista, podríamos entonces añadir un archivo de script extra como fuente, o capturar algo de JavaScript para incluir en nuestro documento.

<?php $this->headScript()->appendFile('/js/user-list.js') ?>
<?php $this->headScript()->captureStart() ?>
site = {
    baseUrl: "<?php echo $this->baseUrl() ?>"
};
<?php $this->headScript()->captureEnd() ?>

Dentro de nuestro script de layout, simplemente hacemos echo del placeholder, tal como con todos los demás:

<?php echo $this->doctype() ?>
<html>
    <?php echo $this->headTitle() ?>
    <?php echo $this->headLink() ?>
    <?php echo $this->headScript() ?>
    <!-- ... -->

Esto generará la siguiente salida:

<script type="text/javascript" src="/js/site.js"></script>
<script type="text/javascript" src="/js/user-list.js"></script>
<script type="text/javascript">
site = {
    baseUrl: "<?php echo $this->baseUrl() ?>"
};
</script>
[Note] Variante InlineScript

Muchos navegadores a menudo bloquean la visualización de una página hasta que todos los scripts y hojas de estilo referenciados en la sección <head> se hayan cargado. Si tiene varias directivas de este tipo, esto puede afectar cuán pronto alguien puede empezar a ver realmente la página.

Una forma de evitar esto es emitir sus etiquetas <script> justo antes de cerrar el <body> de su documento. (Esta es una práctica recomendada específicamente por el proyecto Y! Slow.)

Zend Framework soporta esto de dos formas diferentes:

  • Puede renderizar su etiqueta headScript() donde quiera en su script de layout; solo porque el nombre haga referencia a "head" no significa que deba renderizarse en esa ubicación.

  • Alternativamente, puede usar el helper inlineScript(), que es simplemente una variante de headScript(), y mantiene el mismo comportamiento, pero usa un registro separado.