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
}
}
]]>