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.
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.
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>
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" />
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>
![]() |
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:
|
![[Note]](images/note.png)