ViewRendererIntroducciónEl 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');
]]>APIEn 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 LookupEl 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ásicoEn 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ónSi 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 AutorenderPara 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 DiferenteAlgunas 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 PathEn 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ónA 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
}
}
]]>