ViewRendererIntroducción
El ayudante ViewRenderer está diseñado para satisfacer
los siguientes objetivos:
Eliminar la necesidad de instanciar objetos de vista dentro
de los controladores; los objetos de vista quedarán
registrados automáticamente con el contralor.
Establece automáticamente el script de vista, el ayudante,
y los paths de los filtros basados en el módulo actual.
Asocia automáticamente el nombre del módulo actual como
un prefijo de clase para las clases ayudante y filtro.
Crea un objeto de vista, disponible globalmente para todos
los controladores y acciones despachados.
Permite al desarrollador establecer por defecto las
opciones de renderizado para todos los controladores.
Agrega la capacidad para renderizar automáticamente los
scripts de vista sin ninguna intervención.
Permite al desarrollador crear sus propias especificaciones
para el path base de vistas y para el path de los scripts
de vista.
Si realiza un _forward(), redirecciona, o
render manualmente, el autorendering no se llevará
a cabo, como está realizando cualquiera de estas acciones le
está diciendo al ViewRenderer que usted está
determinando su propia salida.
El ViewRenderer está habilitado por defecto.
Puede desactivarlo vía parámetro del front controller
noViewRenderer
($front->setParam('noViewRenderer', true)) o
eliminando al ayudante del stack de ayudantes
(Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer')).
Si desea modificar los settings del ViewRenderer
antes de despachar el front controller, puede hacerlo en una
de las dos maneras:
Instanciar y registrar su propio objeto
ViewRenderer y pasarlo al ayudante:
setView($view)
->setViewSuffix('php');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
]]>
Inicializar y/o recuperar un objeto
ViewRenderer por demanda via el ayudante:
setView($view)
->setViewSuffix('php');
]]>API
En su uso más básico, simplemente instancie a
ViewRenderer y páselo al ayudante de acciones.
La forma más fácil para instanciar y registrar de una sola vez es
utilizando el método del ayudante getStaticHelper():
La primera vez que se instancia un controlador de acción, se
disparará ViewRenderer para instanciar al objeto
vista. Cada vez que el controlador es instanciado, se llama al
método init() de ViewRenderer, que lo
llevará a establecer la propiedad del controlador de acción, y
llama a addScriptPath() con un path relativo al
módulo actual; este será llamado con un prefijo de clase nombrada
después del módulo actual, haciendo efectivamente el namespacing de
todas las clases de ayudantes y filtros que define para el módulo.
Cad vez que llama a postDispatch(), este llamará a
render() para la acción actual.
Como ejemplo, considere la siguiente clase:
view->foo = 'bar';
}
}
...
// en uno de sus scripts de vista:
$this->foo(); // llama a Foo_View_Helper_Foo::foo()
]]>
El ViewRenderer también define una serie de accededores
para permitir establecer y recuperar opciones de vista:
setView($view) le permite establecer el objeto
vista para ViewRenderer. Se vuelve como una
propiedad de clase pública $view.
setNeverRender($flag = true) puede ser
utilizado para activar o desactivar globalmente el
autorendering, es decir, para todos los controladores.
Si es verdadero, postDispatch() no llamará
automáticamente a render() en el controlador
actual. getNeverRender() recupera el valor
actual.
setNoRender($flag = true) puede ser utilizado
para activar o desactivar el autorendering.
Si es verdadero, postDispatch() no llamará
automáticamente a render() en el controlador
actual. Este ajuste se reseteará cada vez que se llame a
preDispatch() (es decir, usted necesita
establecer este flag para cada controlador para el cual
no quiera que el autorenderering se ejecute).
getNoRender() recupera el valor actual.
setNoController($flag = true) pude ser usado
para decirle a render() que no busque el
script de acción en un subdirectorio nombrado después de
que el controlador (que es el comportamiento por defecto)
getNoController() recupere el valor actual.
setNeverController($flag = true) es análogo
a setNoController(), pero trabaja a un nivel
global -- es decir, que no se reseteará por cada acción
ejecutada. getNeverController() recupera el
valor actual.
setScriptAction($name) puede ser utilizado para
especificar el script de acción a renderizar.
$name debe ser el nombre del script menos el
sufijo del archivo (y sin el subdirectorio del controlador,
a menos que noController se haya activado).
Si no se ha especificado, busca un script de vista nombrado
después de la acción en el objeto solicitud.
getScriptAction() recupera el valor actual.
setResponseSegment($name) puede ser utilizado
para especificar qué segmento del objeto respuesta nombrado
renderizar. Si no se especifica, se hace en el segmento por
defecto. getResponseSegment() recupera el
valor actual.
initView($path, $prefix, $options) puede ser
llamado para especificar el path base de las vistas,
prefijos de clase para scripts de ayudantes y filtros, y
las opciones de ViewRenderer.
Puede pasar cualquiera de los siguientes flags:
neverRender, noRender,
noController, scriptAction, y
responseSegment.
setRender($action = null, $name = null, $noController
= false) le permite establecer cualquier
scriptAction, responseSegment, y
noController en un pase. direct()
es un alias a este método, permitiéndole llamar a este
método fácilmente dede su controlador:
_helper->viewRenderer('foo');
// render form.phtml al segmento de respuesta de 'html', sin usar un
// subdirectorio de scripts de controladores de acción:
$this->_helper->viewRenderer('form', 'html', true);
]]>setRender() y direct()
realmente no renderiza el script de vista, sino que
establece indicaciones que postDispatch()
y render() utlizarán para renderizar la
vista.
El constructor le permite opcionalmente pasar el objeto vista y las
opciones de ViewRenderer; acepta los mismos flags que
initView():
'UTF-8'));
$options = array('noController' => true, 'neverRender' => true);
$viewRenderer =
new Zend_Controller_Action_Helper_ViewRenderer($view, $options);
]]>
Hay varios métodos adicionales para personalizar especificaciones
del path, usados para determinar el path base del script de vista
para añadir al objeto vista, y el path del script de vista a usar
cuando esté autodeterminando el script de vista a renderizar.
Cada uno de estos métodos toma uno o más de los siguientes
localizadores:
:moduleDir hace referencia a la actual
directorio base del módulo(por convención, el directorio
padre del directorio del módulo controlador).
:module hace referencia al nombre del módulo
actual.
:controller hace referencia al nombre del
controlador actual.
:action hace referencia al nombre de la
acción actual.
:suffix hace referencia al sufijo del script
de vista (que puede ser definido via
setViewSuffix()).
Los métodos para controlar las especificaciones del path son:
setViewBasePathSpec($spec) le permite cambiar
la especificación del path utilizada para determinar el
path base para añadir al objeto vista.
La especificación por defecto es :moduleDir/views.
Puede recuperar la especificación actual en cualquier
momento usando getViewBasePathSpec().
setViewScriptPathSpec($spec) le permite
cambiar el path de la especificación utilizada para
determinar el path a un script de vista individual
(menos el path de la base del script de vista).
La especificación por defecto es
:controller/:action.:suffix.
Puede recuperar la especificación actual en cualquier
momento usando
getViewScriptPathSpec().
setViewScriptPathNoControllerSpec($spec)
le permite cambiar el path de la especificación utilizado
para determinar el path a un script de vista individual
cuando noController está activado
(menos el path base del script de vista). La especificación
por defecto es :action.:suffix. Puede
recuperar la especificación actual en cualquier momento
usando getViewScriptPathNoControllerSpec().
Para un control más refinado sobre el path de especificaciones,
puede usar
Zend_Filter_Inflector.
Bajo el capó, ViewRenderer ya usa un inflector para
realizar mapeos del path. Para interactuar con el inflector
-- ya sea para establecerlo para uso propio, o para modificar el
inflector por defecto, se pueden utilizar los siguientes
métodos:
getInflector() recupera el inflector.
Si no existe todavía en ViewRenderer, se crea
uno utilizando las reglas predeterminadas.
Por defecto, utiliza reglas de referencias estáticas para el
sufijo y directorio de módulos, así como una meta estática;
esto permite que diversas propiedades de
ViewRenderer tengan la capacidad de
modificar dinámicamente al inflector.
setInflector($inflector, $reference) permite
establecer un inflector personalizado para usar con
ViewRenderer. Si $reference es
verdadero, establecerá el sufijo y directorio de módulos
como referencias estáticas a las propiedades de
ViewRenderer, así como al objetivo.
Convenciones por Defecto para Lookup
El ViewRenderer hace algún tipo de normalización
del path para facilitar la búsqueda de los scripts de vista.
Las reglas predeterminadas son los siguientes:
:module: MixedCase y camelCasedWords
están separados por guiones, y el string completo se
convierte a minúsculas.
Por ejemplo: "FooBarBaz" pasa a ser "foo-bar-baz".
Internamente, el inflector utiliza los filtros
Zend_Filter_Word_CamelCaseToDash
y Zend_Filter_StringToLower.
:controller: MixedCase y camelCasedWords
están separados por guiones; los subrayados se
convierten en separadores de directorio , y el string
emitido a minúsculas.
Ejemplos: "FooBar" pasa a ser "foo-bar";
"FooBar_Admin" pasa a ser "foo-bar/admin".
Internamente, el inflector utiliza los filtros
Zend_Filter_Word_CamelCaseToDash,
Zend_Filter_Word_UnderscoreToSeparator,
y Zend_Filter_StringToLower.
:action: MixedCase y camelCasedWords
están separados por guiones; los caracteres
no alfanuméricos son traducidos a guiones,
y el string emitido a minúsculas.
Ejemplos: "fooBar" pasa a ser "foo-bar";
"foo-barBaz" pasa a ser "foo-bar-baz".
Internamente, el inflector utiliza los filtros
Zend_Filter_Word_CamelCaseToDash,
Zend_Filter_PregReplace, y
Zend_Filter_StringToLower.
Los últimos temas en la API de ViewRenderer son los
métodos para determinar realmente los paths de los scripts de vista
y el rendering de las vistas.
Estos incluyen:
renderScript($script, $name) permite renderizar
un script con una ruta que especifique, opcionalmente a
un segmento nombrado del path. Cuando se utiliza este
método, ViewRenderer no autodetermina el
nombre del script, en cambio pasa directamente a
$script el argumento directamente al método
del objeto vista render().
Una vez que la vista ha sido renderizada al objeto respuesta,
se establece noRender para evitar
accidentalmente renderizar el mismo script de vista varias
veces.
Por defecto,
Zend_Controller_Action::renderScript()
le delega a ViewRenderer el método
renderScript().
getViewScript($action, $vars) crea el path a
un script de vista basado en la acción pasada y/o cualquier
variables pasadas en $vars.
Las claves para este array pueden incluir cualquiera de las
claves de especificación de paths ('moduleDir',
'module', 'controller', 'action', y 'suffix').
Se utilizarán cualquiera de la variables pasadas;
de lo contrario, se utilizarán valores basados en la
petición actual.
getViewScript() utilizará tanto a
viewScriptPathSpec o
viewScriptPathNoControllerSpec sobre la base
establecida del flag noController.
Los delimitadores de palabras encontrados en un módulo,
controlador o nombres de acción serán reemplazados por
guiones ('-'). Así pues, si tiene el nombre de controlador
'foo.bar' y la acción 'baz:bat', utilizando la
especificación por defecto del path se traducirá en un
path al script de vista 'foo-bar/baz-bat.phtml'.
Por defecto,
Zend_Controller_Action::getViewScript()
delega el método getViewScript() de
ViewRenderer.
render($action, $name, $noController)
comprueba primero para ver si bien $name o
$noController se han pasado, y si es así,
establece los flags apropiados (responseSegment y
noController, respectivamente) en ViewRenderer.
A continuación, pasa el argumento $action,
si hay alguno, a getViewScript().
Por último, pasa el path calculado del script de vista a
renderScript().
Hay que ser conscientes de los efectos secundarios al
usar render(): los valores que usted pasa para el nombre
del segmento respuesta y para el flag noController
persistirán en el objeto. Además, noRender será
establecido después de completar la renderización.
Por defecto,
Zend_Controller_Action::render()
delega a ViewRenderer el método
render().
renderBySpec($action, $vars, $name)
permite pasar variables de especificación del path a fin de
determinar el path para la creación del script de vista.
Este pasa $action y $vars a
getScriptPath(), y luego pasa el path del
script resultante y $name a
renderScript().
Ejemplos Uso BásicoUso Básico
En lo más básico, usted simplemente inicializa y registra el
ayudante ViewRenderer con el ayudante broker
en su bootstrap, y luego establecer las variables en sus
métodos de acción.
view->foo = 'bar';
}
// No hace rendering, ya que salta a otra acción; la nueva acción
// realizará cualquier rendering
public function bazAction()
{
$this->_forward('index');
}
// No hace rendering, ya que redirecciona a otra ubicación
public function batAction()
{
$this->_redirect('/index');
}
}
]]>Convenciones de Nombres: Delimitadores de Palabras en Controladores y Nombres de Acción
Si su controlador o nombre de acción está compuesto por varias
palabras, el despachador exige que estos sean separados de la URL
por un path específico y caracteres delimitadores de palabras.
El ViewRenderer reemplaza cualquier delimitador
de paths encontrado en el nombre del controlador con el
delimitador actual ('/'), y cualquier delimitador de palabra
encontrado con un guión ('-') cuando crea paths.
Así, una llamada a la acción
/foo.bar/baz.bat despachará a
FooBarController::bazBatAction() en
FooBarController.php, el cual renderizaría a
foo-bar/baz-bat.phtml; una llamada a la acción
/bar_baz/baz-bat despachará a
Bar_BazController::bazBatAction() en
Bar/BazController.php (note la separación del path)
y renderiza bar/baz/baz-bat.phtml.
Tener en cuenta que el en el segundo ejemplo, el módulo es
todavía el módulo por defecto, pero que, debido a la
existencia de un separador de paths, el controlador recibe el
nombre Bar_BazController, en
Bar/BazController.php.
El ViewRenderer imita la jerarquía del directorio del
controlador.
Deshabilitando Autorender
Para algunas acciones o controladores, usted puede querer apagar
el autorendering -- por ejemplo, si quiere emitir un tipo
diferente de salida (XML, JSON, etc), o si simplemente no desea
emitir nada.
Tiene dos opciones: apagar todos los casos de autorendering
(setNeverRender()), o simplemente desactivarlo
para la acción actual (setNoRender()).
_helper->viewRenderer->setNoRender();
}
}
// Bat clase del controlador, bar módulo:
class Bar_BatController extends Zend_Controller_Action
{
public function preDispatch()
{
// Nunca auto renderizar las acciones de este controlador
$this->_helper->viewRenderer->setNoRender();
}
}
]]>
En muchos casos, no tiene sentido desactivar el autorendering
globalmente (ala setNeverRender()), y la única
cosa que puede ganar de ViewRenderer es el
autosetup del objeto de vista.
Eligiendo Un Script de Vista Diferente
Algunas situaciones requieren renderizar un script diferente
al llamado después de la acción. Por ejemplo, si tiene un
controlador que tiene tanto las acciones de agregar y de editar,
ambos pueden mostrar la misma vista 'form', aunque con diferentes
valores establecidos. Puede cambiar fácilmente el nombre
del script usado tanto con
setScriptAction(), setRender(), o
llamando al ayudante como un método, que invocará a
setRender().
_helper->viewRenderer('form');
}
public function editAction()
{
// Render 'bar/form.phtml' en lugar de 'bar/edit.phtml'
$this->_helper->viewRenderer->setScriptAction('form');
}
public function processAction()
{
// hacer alguna validación...
if (!$valid) {
// Render 'bar/form.phtml' en lugar de 'bar/process.phtml'
$this->_helper->viewRenderer->setRender('form');
return;
}
// de otra manera, continuar procesando...
}
}
]]>Modificando la Vista Registrada
¿Y si se necesita modificar el objeto vista --
por ejemplo, cambiar el ayudante de paths, o la codificación?.
Puede hacerlo ya sea por modificar el objeto vista establecido
en su controlador, o arrebatándole el objeto vista a
ViewRenderer; ambas son referencias al mismo objeto.
view->setEncoding('UTF-8');
}
public function bazAction()
{
// Obtener el objeto vista y establecer
// el callback de escape a 'htmlspecialchars'
$view = $this->_helper->viewRenderer->view;
$view->setEscape('htmlspecialchars');
}
}
]]>Ejemplos de Uso AvanzadoCambiando las Especificaciones del Path
En algunas circunstancias, puede decidir que las
especificaciones del path por defecto no se adaptan a su sitio.
Por ejemplo, usted puede querer tener un árbol único de
plantillas al que puede dar acceso a sus diseñadores
(esto es muy típico cuando se utiliza
Smarty, por
ejemplo). En ese caso, puede querer embeber los datos de la
especificación del path base de la vista, y crear una
especificación alternativa para el script de vista del path
ellos mismos.
Para los fines de este ejemplo, supongamos que el path base
de las vistas debería ser '/opt/vendor/templates', y que desea
para que los scripts de vista sean referenciados por
':moduleDir/:controller/:action.:suffix'; si el flag
noController ha sido establecido, quiere renderizar
fuera del nivel superior en lugar de en un subdirectorio
(':action.:suffix'). Por último, que quiere utilizar 'tpl'
como el sufijo del nombre de archivo del script de vista.
setViewBasePathSpec('/opt/vendor/templates')
->setViewScriptPathSpec(':module/:controller/:action.:suffix')
->setViewScriptPathNoControllerSpec(':action.:suffix')
->setViewSuffix('tpl');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
]]>Rendering Múltiples Scripts de Vista desde una Sola Acción
A veces, puede que necesite renderizar múltiples scripts de
vista desde una sola acción. Esto es muy sencillo --
simplemente hacer múltiples llamadas a render():
model es el modelo actual
$this->view->results =
$this->model->find($this->_getParam('query', '');
// render() por defecto lo delega al ViewRenderer
// Render primero al from de búsqueda y luego los resultados
$this->render('form');
$this->render('results');
}
public function formAction()
{
// No hacer nada; ViewRenderer hace autorender del script de vista
}
}
]]>