ViewRendererIntroduction
L'aide ViewRenderer apporte les comportements suivants :
Élimine le besoin d'instancier un objet de vue dans ses contrôleurs. Ceci
devient automatique.
Configure automatiquement les chemins vers les scripts de vue, les aides,
et les filtres, en se basant sur le module actuel et associe le nom du module
comme préfixe de classe pour les aides et les filtres.
Créer un objet de vue général accessible pour tous les contrôleurs et
donc pour toutes les actions disptachées.
Autorise le développeur à personnaliser les options de rendu de la vue.
Donne la possibilité de rendre automatiquement un script de vue.
Donne accès aux paramètres configurant le chemin de base (base path) et
le chemin des scripts (script path), de la vue.
Su vous utilisez _forward(),
redirect(), ou render()
manuellement, le rendu automatique sera annulé car
ViewRenderer saura que vous prenez la main.
Le ViewRenderer est activé par défaut dans le contrôleur
frontal. Pour le désactiver, utilisez le paramètre
noViewRenderer
($front->setParam('noViewRenderer', true);) ou retirez
l'objet du gestionnaire d'aides
(Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer')).
Si vous voulez modifier un paramètre du ViewRenderer avant la
distribution du contrôleur frontal, il existe deux moyens :
Instanciez et enregistrez votre propre objet
ViewRenderer et passez le au gestionnaire
d'aides :
setView($view)
->setViewSuffix('php');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
]]>
Initialisez et/ou récupérez l'objet
ViewRenderer via le gestionnaire d'aides :
setView($view)
->setViewSuffix('php');
]]>API
L'usage le plus banal consiste à instancier et passer l'objet
ViewRenderer au gestionnaire d'aides. La manière la plus simple
est d'utiliser la méthode statique getStaticHelper()
du gestionnaire, qui s'occupe de tout ceci en une passe :
La première action demandée déclenche l'instanciation de l'objet de vue par le
ViewRenderer. A chaque instanciation de contrôleur, la
méthode init() de l'objet
ViewRenderer est appelée. Elle va configurer la vue et appeler
addScriptPath() avec un chemin relatif au dossier courant.
Ceci a pour effet de "namespacer" toutes les aides et les filtres de vue pour le
module en cours.
A chaque postDispatch() d'action,
render() est appelée.
Voici un exemple :view->foo = 'bar';
}
}
...
// Dans un des scripts de vue :
$this->foo(); // appelle Foo_View_Helper_Foo::foo()
]]>
Le ViewRenderer définit de même des accesseurs pour configurer la
vue qu'il encapsule :
setView($view) Passage de l'objet de vue au
ViewRenderer. Il devient accessible comme une propriété
publique de l'objet : $view.
setNeverRender($flag = true) peut être utilisée pour
désactiver le rendu automatique de la vue dans tous les contrôleurs.
Si réglé à TRUEpostDispatch() ne va pa automatiquement appeler
render() dans le contrôleur courant.
getNeverRender() retourne ce paramètre.
setNoRender($flag = true) peut être utilisée pour
désactiver le rendu automatique de la vue dans le contrôleur actuel.
Si réglé à TRUEpostDispatch() ne va pa automatiquement appeler
render() dans le contrôleur courant, mais
preDispatch() réactive le paramètre pour l'action
suivante. getNoRender() retourne cette option.
setNoController($flag = true) est utilisée pour
spécifier à render() de ne pas chercher le script
de vue dans le sous répertoire après le contrôleur (correspondant à l'action).
Par défaut, cette recherche est effectuée.
getNoController() retourne ce paramètre.
setNeverController($flag = true) fonctionne de manière
similaire à setNoController(), mais pour tous les
contrôleurs.getNeverController() est l'autre
accesseur.
setScriptAction($name) peut être utilisée pour
spécifier le script de vue d'une action à rendre. $name
doit être le nom de l'action sans le suffixe (et sans le nom du contrôleur
sauf si noController a été activé). Si vous n'utilisez
pas cette méthode elle cherchera le script de vue correspondant au nom de
l'action en cours (issue de l'objet de requête).
getScriptAction() retourne la valeur actuelle de ce
paramètre.
setResponseSegment($name) dit dans quel segment de la
réponse rendre le script. Par défaut, la vue est rendue dans le segment par
défaut. getResponseSegment() retourne cette valeur.
initView($path, $prefix, $options) doit être appelée
pour configurer la vue : son "base path", le préfixe de classe pour les filtres
et aides, et des options du ViewRenderer matérialisées
par : neverRender, noRender,
noController, scriptAction, et
responseSegment.
setRender($action = null, $name = null, $noController =
false) vous permet de spécifier les paramètres
scriptAction, responseSegment, et
noController en une fois.
direct() est un alias qui permet un appel rapide
depuis le contrôleur :
_helper->viewRenderer('foo');
// rend form.phtml dans le segment 'html' de la réponse sans utiliser le
// sous repertoire contrôleur pour chercher le script de vue :
$this->_helper->viewRenderer('form', 'html', true);
]]>setRender() et direct()
ne rendent pas un script de vue à proprement parler, mais elles notifient
au postDispatch() et
render() sera utilisée pour le faire.
Le constructeur de ViewRenderer accepte aussi un objet de vue et
un tableau d'options, de la même manière que initView() :
'UTF-8'));
$options = array('noController' => true, 'neverRender' => true);
$viewRenderer =
new Zend_Controller_Action_Helper_ViewRenderer($view, $options);
]]>
Il est aussi possible de personnaliser les chemins utilisés pour déterminer le
base path (chemin de base) de la vue ainsi que le script path (chemin vers les scripts
de vue). Des méthodes le permettent, utilisez les options suivantes avec :
:moduleDir représente le module courant (par convention le
dossier parent au dossier contrôleur).
:module pointe vers le module actuel.:controller pointe vers le contrôleur actuel.:action représente l'action actuellement traitée.:suffix est utilisée pour le suffixe du script de vue.
setViewSuffix() permet aussi de le modifier.
Toutes ces options s'utilisent avec les méthodes ci-après :setViewBasePathSpec($spec) vous permet de changer le
dossier donnant accès aux dossiers de la vue : le base path. Par défaut
il s'agit de :moduleDir/views. L'accesseur de récupération
est getViewBasePathSpec().
setViewScriptPathSpec($spec) : une fois dans le base
path, le rendu cherche le script de vue dans le script path, que cette méthode
permet de définir. La valeur par défaut est
:controller/:action.:suffix et
l'autre accesseur est getViewScriptPathSpec().
setViewScriptPathNoControllerSpec($spec) Une fois
dans le base path, si noController est activé, le rendu
cherche le script de vue dans le chemin que cette méthode permet de définir.
La valeur par défaut est :action.:suffix et l'autre
accesseur est getViewScriptPathNoControllerSpec().
ViewRenderer utilise un inflecteur :
Zend_Filter_Inflector, pour résoudre les
options de chemin, en chemins réels. Pour une personnalisation maximale, vous pouvez
interagir avec cet inflecteur à l'aide des méthodes suivantes :
getInflector() retourne l'inflecteur. Si aucun
n'existe, ViewRenderer en crée un avec des options par
défaut.
Par défaut, les règles de l'inflecteur sont statiques autant pour le
suffixe et le répertoire module, que pour la cible. Ceci permet au
ViewRenderer de modifier ces valeurs dynamiquement.
setInflector($inflector, $reference) peut être
utilisée pour passer son propre inflecteur à
ViewRenderer. Si $reference est à
TRUE, alors le suffixe, le répertoire du module et
la cible seront affectés en fonction des propriétés de
ViewRenderer.
Règles de résolution par défaut
Le ViewRenderer utilise certaines règles par défaut pour
chercher ses scripts de vue, voyez plutôt :
:module : casseMélangée et motsEnNotationCamel
qui deviennent des mots séparés par des tirets, et en minuscules.
"FooBarBaz" devient "foo-bar-baz".
En interne, l'inflecteur utilise les filtres
Zend_Filter_Word_CamelCaseToDash et
Zend_Filter_StringToLower.
:controller : casseMélangée et
motsEnNotationCamel qui deviennent des mots séparés par des tirets ;
les tirets bas eux, se transforment en séparateur de dossier et tout est
passé en minuscules. "FooBar" devient
"foo-bar" ; "FooBar_Admin"
devient "foo-bar/admin".
En interne, l'inflecteur utilise les filtres
Zend_Filter_Word_CamelCaseToDash,
Zend_Filter_Word_UnderscoreToSeparator, et
Zend_Filter_StringToLower.
:action : casseMélangée et motsEnNotationCamel
qui se transforment en mots séparés par des tirets, minuscules. Les
caractères non alphanumériques deviennent des tirets. "fooBar" devient
"foo-bar" ; "foo-barBaz" devient "foo-bar-baz".
Pour ceci, l'inflecteur interne utilise les filtres
Zend_Filter_Word_CamelCaseToDash,
Zend_Filter_PregReplace, et
Zend_Filter_StringToLower.
Enfin, l'API de ViewRenderer vous propose
aussi des méthodes pour déterminer les scripts de vue, et rendre la vue. Celles-ci
se décomposent en :
renderScript($script, $name) va vous permettre de
spécifier pleinement le script de vue à rendre, et éventuellement un nom de
segment de réponse dans lequel rendre. ViewRenderer
s'attend à un paramètre $script représentant un chemin
complet vers un script de vue, telle que la méthode de la vue
render() l'attend.
Une fois rendue, la vue utilise noRender pour éviter
un double rendu automatisé.
Par défaut, Zend_Controller_Action::renderScript()
est un proxy vers la méthode renderScript() de
ViewRenderer.
getViewScript($action, $vars) récupère le chemin du
script de vue en se basant sur les paramètres $action et $vars.
$vars peut contenir "moduleDir", "module", "controller",
"action", et "suffix"), sinon les valeurs de la requête actuelle seront
utilisées.
getViewScript() utilisera
viewScriptPathSpec ou
viewScriptPathNoControllerSpec selon le paramètre
noController.
Les délimiteurs apparaissant dans les modules, contrôleurs ou actions seront
remplacés par des tirets ("-"). Ainsi pour un contrôleur
"foo.bar" et une action "baz:bat", il
résultera un chemin de vue "foo-bar/baz-bat.phtml".
Par défaut Zend_Controller_Action::getViewScript()
est un proxy vers la méthode getViewScript() de
ViewRenderer.
render($action, $name, $noController) a beaucoup de
responsabilités : d'abord, elle vérifie si $name ou
$noController lui ont été passés, si c'est le cas, elle
configure correctement les paramètres responseSegment et
noController dans le ViewRenderer. Elle passe ensuite
$action, si spécifié, à
getViewScript(). Enfin, elle
passe le script de vue calculé à renderScript().
Attention aux effets secondaires avec
render() : les valeurs segment de réponse,
et noController vont persister dans l'objet ViewRenderer.
De plus, noRender() va être appelée.
Par défaut, Zend_Controller_Action::render()
est un proxy vers render() de
ViewRenderer.
renderBySpec($action, $vars, $name) vous fournit le
moyen de passer des paramètres de spécification pour le dossier de script de
vue. Cette méthode passe $action et $vars
à getScriptPath(), pour en déduire un chemin qu'elle
envoie alors avec $name à
renderScript().
ExemplesUsage de base
L'utilisation la plus basique consiste à initialiser ou et enregistrer un
objet ViewRenderer dans le gestionnaire d'aides (helper
broker), et ensuite lui passer des variables dans vos contrôleurs.
view->foo = 'bar';
}
// Ne rend rien, car on demande un nouveau jeton de distribution
public function bazAction()
{
$this->_forward('index');
}
// Ne rend rien, une redirection est demandée
public function batAction()
{
$this->_redirect('/index');
}
}
]]>
Conventions de noms : délimiteurs de mots dans les noms de contrôleur et
d'action
Si les noms de votre contrôleur ou de votre action sont composés de plusieurs
mots, le distributeur s'attend à ce qu'ils soient séparés par des caractères bien
définis, dans l'URL. Le ViewRenderer les
transforme alors en '/' pour les chemins, ou tirets '-' pour les mots. Ainsi, un
appel à /foo.bar/baz.bat distribuera
FooBarController::bazBatAction() dans
FooBarController.php, et ceci rendra
foo-bar/baz-bat.phtml. Un appel à
/bar_baz/baz-bat distribuera vers
Bar_BazController::bazBatAction() dans
Bar/BazController.php (notez la séparation du chemin),
et rend bar/baz/baz-bat.phtml.
Notez dans le second exemple, le module est celui par défaut, mais comme un
séparateur de chemin (tiret bas ou "_") est donné, alors le contrôleur distribué
devient Bar_BazController, dans
Bar/BazController.php.
Désactivation du rendu automatique
Il peut être nécessaire dans certains cas de désactiver manuellement le rendu
automatique de vue effectué par ViewRenderer. Par exemple, si le contrôleur doit
retourner une sortie spéciale, comme XML ou
JSON. Deux options s'offrent à vous :
setNeverRender()) et
setNoRender().
_helper->viewRenderer->setNoRender();
}
}
// Bat controller class, bar module :
class Bar_BatController extends Zend_Controller_Action
{
public function preDispatch()
{
// Ne rend plus aucune action de ce contrôleur
$this->_helper->viewRenderer->setNoRender();
}
}
]]>
Utiliser setNeverRender()), pour désactiver totalement
le rendu automatique de vue vous fera perdre un des avantages majeur de
ViewRenderer.
Choix d'un script de vue différent
Il peut arriver que vous éprouviez le besoin de rendre un script de vue
différent de celui correspondant à l'action en cours de distribution. Par exemple,
un contrôleur qui possède deux actions ajout et édition, qui sont susceptibles
toutes les deux de rendre le même script de vue. Utilisez alors
setScriptAction(), setRender(),
ou appelez directement l'aide ViewRenderer qui invoquera
setRender() :
_helper->viewRenderer('form');
}
public function editAction()
{
// Rend 'bar/form.phtml' au lieu de 'bar/edit.phtml'
$this->_helper->viewRenderer->setScriptAction('form');
}
public function processAction()
{
// un peu de validation...
if (!$valid) {
// Rend 'bar/form.phtml' à la place de 'bar/process.phtml'
$this->_helper->viewRenderer->setRender('form');
return;
}
// continue le processus...
}
}
]]>Modification de l'objet de vue
Si vous désirez modifier l'objet de vue absorbé par
ViewRenderer, pour par exemple ajouter un chemin vers des aides
spécifique, ou spécifier l'encodage, vous pourriez par exemple récupérer l'objet de
vue depuis le ViewRenderer, ou dans un contrôleur.
view->setEncoding('UTF-8');
}
public function bazAction()
{
// Récupère l'objet de vue, et lui passe la fonction
// d'2chappement 'htmlspecialchars'
$view = $this->_helper->viewRenderer->view;
$view->setEscape('htmlspecialchars');
}
}
]]>Utilisation avancéeChangement des spécifications de dossier
Dans certains cas, il peut être nécessaire d'utiliser un chemin absolu, fixe.
Par exemple si vous ne donnez accès à vos graphistes qu'à un seul dossier, en
utilisant un moteur de template tel que
Smarty.
Pour ceci, imaginons que le base path soit fixé à
"/opt/vendor/templates", et
que vous voulez que vos scripts de vues soit référencés par
":moduleDir/:controller/:action.:suffix"; si le paramètre
noController est activé, vous désirez utiliser le dossier
plus haut ":action.:suffix". Enfin,
vous désirez un suffixe en "tpl" :
setViewBasePathSpec('/opt/vendor/templates')
->setViewScriptPathSpec(':module/:controller/:action.:suffix')
->setViewScriptPathNoControllerSpec(':action.:suffix')
->setViewSuffix('tpl');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
]]>Rendu de plusieurs scripts de vue dans une même action
Afin de rendre plusieurs scripts de vue dans une même action, appelez tout
simplement plusieurs fois render() :
model comme étant un modèle valide
$this->view->results = $this->model
->find($this->_getParam('query', '');
// render() est proxiée vers ViewRenderer
// Rend d'abord un formulaire, puis un résultat
$this->render('form');
$this->render('results');
}
public function formAction()
{
// Rien : ViewRenderer rend automatiquement un script de vue
}
}
]]>