| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 24249 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.view.scripts">
- <title>Scripts de vue</title>
- <para>
- Une fois que le contrôleur a assigné les variables et appelé <methodname>render()</methodname>,
- <classname>Zend_View</classname> inclue le script de vue requis et l'exécute "à l'intérieur"
- de la portée de l'instance <classname>Zend_View</classname>. Donc dans vos scripts de vue,
- les références à <varname>$this</varname> pointent en fait sur l'instance
- <classname>Zend_View</classname> elle-même.
- </para>
- <para>
- Les variables assignées à la vue depuis le contrôleur lui sont référées comme des
- propriétés de l'instance. Par exemple, si le contrôleur a assigné une variable
- "quelquechose", vous vous référerez à cette variable par <code>$this->quelquechose</code>
- dans le script de vue. (Cela vous permet de garder une trace pour savoir quelles valeurs ont
- été assignées au script, et lesquelles sont internes au script lui même.)
- </para>
- <para>
- Pour rappel, voici l'exemple de script issu de l'introduction de ce chapitre sur
- <classname>Zend_View</classname>.
- </para>
- <programlisting language="php"><![CDATA[
- <?php if ($this->livres): ?>
- <!-- La table des livres -->
- <table>
- <tr>
- <th>Auteur</th>
- <th>Titre</th>
- </tr>
- <?php foreach ($this->livres as $cle => $livre): ?>
- <tr>
- <td><?php echo $this->escape($livre['auteur']) ?></td>
- <td><?php echo $this->escape($livre['titre']) ?></td>
- </tr>
- <?php endforeach; ?>
- </table>
- <?php else: ?>
- <p>Aucun livre à afficher</p>
- <?php endif; ?>
- ]]></programlisting>
- <sect2 id="zend.view.scripts.escaping">
- <title>Échapper la sortie</title>
- <para>
- Une des tâches les plus importantes à effectuer dans un script de vue est de
- s'assurer que la sortie est correctement échappée ; de plus ceci permet d'éviter les
- attaques de type cross-site scripting (XSS). A moins que vous n'utilisiez une fonction,
- une méthode, ou une aide qui gère l'échappement, vous devriez toujours échapper les
- variables lors de l'affichage.
- </para>
- <para>
- <classname>Zend_View</classname> a une méthode appelée <methodname>escape()</methodname> qui
- se charge de l'échappement.
- </para>
- <programlisting language="php"><![CDATA[
- // mauvaise pratique d'affichage
- echo $this->variable;
- // bonne pratique d'affichage
- echo $this->escape($this->variable);
- ]]></programlisting>
- <para>
- Par défaut, la méthode <methodname>escape()</methodname> utilise la fonction <acronym>PHP</acronym>
- <methodname>htmlspecialchar()</methodname> pour l'échappement. Cependant, en fonction de votre
- environnement, vous souhaitez peut-être un échappement différent. Utilisez la méthode
- <methodname>setEscape()</methodname> au niveau du contrôleur pour dire à
- <classname>Zend_View</classname> quelle méthode de rappel ("callback") elle doit
- utiliser.
- </para>
- <programlisting language="php"><![CDATA[
- // crée une instance Zend_View
- $view = new Zend_View();
- // spécifie qu'il faut utiliser htmlentities
- // comme rappel d'échappement
- $view->setEscape('htmlentities');
- // ou spécifie qu'il faut utiliser une méthode statique
- // comme rappel d'échappement
- $view->setEscape(array('UneClasse', 'nomDeMethode'));
- // ou alors une méthode d'instance
- $obj = new UneClasse();
- $view->setEscape(array($obj, 'nomDeMethode'));
- // et ensuite effectue le rendu de la vue
- echo $view->render(...);
- ]]></programlisting>
- <para>
- La fonction ou méthode de rappel doit prendre la valeur à échapper dans le premier
- paramètre, et tous les autres paramètres devraient être optionnels.
- </para>
- </sect2>
- <sect2 id="zend.view.scripts.templates">
- <title>Utiliser des systèmes de gabarit (template) alternatifs</title>
- <para>
- Bien que <acronym>PHP</acronym> lui-même un moteur de gabarit puissant, beaucoup de développeurs
- pensent que c'est beaucoup trop puissant ou complexe pour les graphistes/intégrateurs et
- veulent utiliser un moteur de template alternatif. <classname>Zend_View</classname>
- fournit deux mécanismes pour faire cela, le premier à travers les scripts de vues, le
- second en implémentant <classname>Zend_View_Interface</classname>.
- </para>
- <sect3 id="zend.view.scripts.templates.scripts">
- <title>Système de gabarit utilisant les scripts de vues</title>
- <para>
- Un script de vue peut être utilisé pour instancier et manipuler un objet de
- gabarit séparé, comme un gabarit de type PHPLIB. Le script de vue pour ce type
- d'activité pourrait ressembler à ceci :
- </para>
- <programlisting language="php"><![CDATA[
- include_once 'template.inc';
- $tpl = new Template();
- if ($this->livres) {
- $tpl->setFile(array(
- "listelivre" => "listelivre.tpl",
- "chaquelivre" => "chaquelivre.tpl",
- ));
- foreach ($this->livres as $cle => $livre) {
- $tpl->set_var('auteur', $this->escape($livre['auteur']);
- $tpl->set_var('titre', $this->escape($livre['titre']);
- $tpl->parse("livre", "chaquelivre", true);
- }
- $tpl->pparse("output", "listelivre");
- } else {
- $tpl->setFile("nobooks", "pasdelivres.tpl")
- $tpl->pparse("output", "pasdelivres");
- }
- ]]></programlisting>
- <para>Et ceci pourrait être les fichiers de gabarits correspondants :</para>
- <programlisting language="html"><![CDATA[
- <!-- listelivre.tpl -->
- <table>
- <tr>
- <th>Auteur</th>
- <th>Titre</th>
- </tr>
- {livres}
- </table>
- <!-- chaquelivre.tpl -->
- <tr>
- <td>{auteur}</td>
- <td>{title}</td>
- </tr>
- <!-- pasdelivres.tpl -->
- <p>Aucun livre à afficher</p>
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.view.scripts.templates.interface">
- <title>Système de gabarit utilisant Zend_View_Interface</title>
- <para>
- Certains peuvent trouver plus facile de simplement fournir un moteur de
- gabarit compatible avec <classname>Zend_View</classname>.
- <classname>Zend_View_Interface</classname> définit l'interface de compatibilité
- minimale nécessaire :
- </para>
- <programlisting language="php"><![CDATA[
- /**
- * Retourne l'objet moteur de gabarit actuel
- */
- public function getEngine();
- /**
- * Affecte le dossier des scripts de gabarits
- */
- public function setScriptPath($path);
- /**
- * Règle un chemin de base pour toutes les ressources de vue
- */
- public function setBasePath($path, $prefix = 'Zend_View');
- /**
- * Ajoute un chemin de base supplémentaire pour les ressources de vue
- */
- public function addBasePath($path, $prefix = 'Zend_View');
- /**
- * Récupère les chemins actuels vers les ressources de vue
- */
- public function getScriptPaths();
- /**
- * Méthode à surcharger pour affecter les variables des gabarits
- * en tant que propriétés de l'objet
- */
- public function __set($key, $value);
- public function __isset($key);
- public function __unset($key);
- /**
- * Affectation manuelle de variable de gabarit, ou possibilité
- * d'affecter des variables en masse.
- */
- public function assign($spec, $value = null);
- /**
- * Efface toutes les variables du gabarit déjà affectées
- */
- public function clearVars();
- /**
- * Effectue le rendu du gabarit nommé $name
- */
- public function render($name);
- ]]></programlisting>
- <para>
- En utilisant cette interface, il devient relativement facile d'encapsuler un
- moteur de gabarit tiers comme une classe compatible
- <classname>Zend_View</classname>. Comme par exemple, le code suivant est une
- encapsulation potentielle de Smarty :
- </para>
- <programlisting language="php"><![CDATA[
- class Zend_View_Smarty implements Zend_View_Interface
- {
- /**
- * Objet Smarty
- * @var Smarty
- */
- protected $_smarty;
- /**
- * Constructeur
- *
- * @param string $tmplPath
- * @param array $extraParams
- * @return void
- */
- public function __construct($tmplPath = null,
- $extraParams = array())
- {
- $this->_smarty = new Smarty;
- if (null !== $tmplPath) {
- $this->setScriptPath($tmplPath);
- }
- foreach ($extraParams as $key => $value) {
- $this->_smarty->$key = $value;
- }
- }
- /**
- * Retourne l'objet moteur de gabarit
- *
- * @return Smarty
- */
- public function getEngine()
- {
- return $this->_smarty;
- }
- /**
- * Affecte le dossier des scripts de gabarits
- *
- * @param string $path Le répertoire à affecter au path
- * @return void
- */
- public function setScriptPath($path)
- {
- if (is_readable($path)) {
- $this->_smarty->template_dir = $path;
- return;
- }
- throw new Exception('Répertoire fourni invalide');
- }
- /**
- * Récupère le dossier courant des gabarits
- *
- * @return string
- */
- public function getScriptPaths()
- {
- return array($this->_smarty->template_dir);
- }
- /**
- * Alias pour setScriptPath
- *
- * @param string $path
- * @param string $prefix Unused
- * @return void
- */
- public function setBasePath($path, $prefix = 'Zend_View')
- {
- return $this->setScriptPath($path);
- }
- /**
- * Alias pour setScriptPath
- *
- * @param string $path
- * @param string $prefix Unused
- * @return void
- */
- public function addBasePath($path, $prefix = 'Zend_View')
- {
- return $this->setScriptPath($path);
- }
- /**
- * Affectation une variable au gabarit
- *
- * @param string $key Le nom de la variable
- * @param mixed $val La valeur de la variable
- * @return void
- */
- public function __set($key, $val)
- {
- $this->_smarty->assign($key, $val);
- }
- /**
- * Autorise le fonctionnement du test avec empty() and isset()
- *
- * @param string $key
- * @return boolean
- */
- public function __isset($key)
- {
- return (null !== $this->_smarty->get_template_vars($key));
- }
- /**
- * Autorise l'effacement de toutes les variables du gabarit
- *
- * @param string $key
- * @return void
- */
- public function __unset($key)
- {
- $this->_smarty->clear_assign($key);
- }
- /**
- * Affectation de variables au gabarit
- *
- * Autorise une affectation simple (une clé => une valeur)
- * OU
- * le passage d'un tableau (paire de clé => valeur)
- * à affecter en masse
- *
- * @see __set()
- * @param string|array $spec Le type d'affectation à utiliser
- (clé ou tableau de paires clé => valeur)
- * @param mixed $value (Optionel) Si vous assignez une variable nommée,
- utilisé ceci comme valeur
- * @return void
- */
- public function assign($spec, $value = null)
- {
- if (is_array($spec)) {
- $this->_smarty->assign($spec);
- return;
- }
- $this->_smarty->assign($spec, $value);
- }
- /**
- * Effacement de toutes les variables affectées
- *
- * Efface toutes les variables affectées à Zend_View
- * via {@link assign()} ou surcharge de propriété
- * ({@link __get()}/{@link __set()}).
- *
- * @return void
- */
- public function clearVars()
- {
- $this->_smarty->clear_all_assign();
- }
- /**
- * Exécute le gabarit et retourne l'affichage
- *
- * @param string $name Le gabarit à exécuter
- * @return string L'affichage
- */
- public function render($name)
- {
- return $this->_smarty->fetch($name);
- }
- }
- ]]></programlisting>
- <para>
- Dans cet exemple, vous instanciez la classe
- <classname>Zend_View_Smarty</classname> au lieu de <classname>Zend_View</classname>,
- et vous l'utilisez de la même façon :
- </para>
- <programlisting language="php"><![CDATA[
- //Exemple 1a. Dans l'initView() de l'initializer.
- $view = new Zend_View_Smarty('/chemin/vers/les/templates');
- $viewRenderer =
- Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
- $viewRenderer->setView($view)
- ->setViewBasePathSpec($view->_smarty->template_dir)
- ->setViewScriptPathSpec(':controller/:action.:suffix')
- ->setViewScriptPathNoControllerSpec(':action.:suffix')
- ->setViewSuffix('tpl');
- //Exemple 1b. L'utilisation dans le contrôleur d'action reste la même
- class FooController extends Zend_Controller_Action
- {
- public function barAction()
- {
- $this->view->book = 'Zend PHP 5 Certification Study Guide';
- $this->view->author = 'Davey Shafik and Ben Ramsey'
- }
- }
- //Example 2. Initialisation de la vue dans le contrôleur d'action
- class FooController extends Zend_Controller_Action
- {
- public function init()
- {
- $this->view = new Zend_View_Smarty('/path/to/templates');
- $viewRenderer = $this->_helper->getHelper('viewRenderer');
- $viewRenderer->setView($this->view)
- ->setViewBasePathSpec($view->_smarty->template_dir)
- ->setViewScriptPathSpec(':controller/:action.:suffix')
- ->setViewScriptPathNoControllerSpec(':action.:suffix')
- ->setViewSuffix('tpl');
- }
- }
- ]]></programlisting>
- </sect3>
- </sect2>
- </sect1>
|