Zend_View-Scripts.xml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. <!-- EN-Revision: 13826 -->
  2. <sect1 id="zend.view.scripts">
  3. <title>Scripts de vue</title>
  4. <para>Une fois que le contrôleur a assigné les variables et appelé <code>render()</code>, <classname>Zend_View</classname>
  5. 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
  6. dans vos scripts de vue, les références à <code>$this</code> pointent en fait sur l'instance <classname>Zend_View</classname>
  7. elle-même.</para>
  8. <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.
  9. Par exemple, si le contrôleur a assigné une variable "quelquechose", vous vous référerez à cette variable par
  10. <code>$this-&gt;quelquechose</code> dans le script de vue. (Cela vous permet de garder une trace pour savoir quelles
  11. valeurs ont été assignées au script, et lesquelles sont internes au script lui même.)</para>
  12. <para>Pour rappel, voici l'exemple de script issu de l'introduction de ce chapitre sur
  13. <classname>Zend_View</classname>.</para>
  14. <programlisting role="php"><![CDATA[
  15. <?php if ($this->livres): ?>
  16. <!-- La table des livres -->
  17. <table>
  18. <tr>
  19. <th>Auteur</th>
  20. <th>Titre</th>
  21. </tr>
  22. <?php foreach ($this->livres as $cle => $livre): ?>
  23. <tr>
  24. <td><?php echo $this->escape($livre['auteur']) ?></td>
  25. <td><?php echo $this->escape($livre['titre']) ?></td>
  26. </tr>
  27. <?php endforeach; ?>
  28. </table>
  29. <?php else: ?>
  30. <p>Aucun livre à afficher</p>
  31. <?php endif; ?>
  32. ]]></programlisting>
  33. <sect2 id="zend.view.scripts.escaping">
  34. <title>Échapper la sortie</title>
  35. <para>Une des tâches les plus importantes à effectuer dans un script de vue est de s'assurer que la sortie est
  36. correctement échappée ; de plus ceci permet d'éviter les attaques de type cross-site scripting (XSS). A moins
  37. que vous n'utilisiez une fonction, une méthode, ou une aide qui gère l'échappement, vous devriez toujours
  38. échapper les variables lors de l'affichage.</para>
  39. <para><classname>Zend_View</classname> a une méthode appelée <code>escape()</code> qui se charge de l'échappement.</para>
  40. <programlisting role="php"><![CDATA[
  41. // mauvaise pratique d'affichage
  42. echo $this->variable;
  43. // bonne pratique d'affichage
  44. echo $this->escape($this->variable);
  45. ]]></programlisting>
  46. <para>Par défaut, la méthode <code>escape()</code> utilise la fonction PHP <code>htmlspecialchar()</code> pour
  47. l'échappement. Cependant, en fonction de votre environnement, vous souhaitez peut-être un échappement différent.
  48. Utilisez la méthode <code>setEscape()</code> au niveau du contrôleur pour dire à <classname>Zend_View</classname> quelle
  49. méthode de rappel ("callback") elle doit utiliser.</para>
  50. <programlisting role="php"><![CDATA[
  51. // crée une instance Zend_View
  52. $view = new Zend_View();
  53. // spécifie qu'il faut utiliser htmlentities
  54. // comme rappel d'échappement
  55. $view->setEscape('htmlentities');
  56. // ou spécifie qu'il faut utiliser une méthode statique
  57. // comme rappel d'échappement
  58. $view->setEscape(array('UneClasse', 'nomDeMethode'));
  59. // ou alors une méthode d'instance
  60. $obj = new UneClasse();
  61. $view->setEscape(array($obj, 'nomDeMethode'));
  62. // et ensuite effectue le rendu de la vue
  63. echo $view->render(...);
  64. ]]></programlisting>
  65. <para>La fonction ou méthode de rappel doit prendre la valeur à échapper dans le premier paramètre, et tous les
  66. autres paramètres devraient être optionnels.</para>
  67. </sect2>
  68. <sect2 id="zend.view.scripts.templates">
  69. <title>Utiliser des systèmes de gabarit (template) alternatifs</title>
  70. <para>Bien que PHP lui-même un moteur de gabarit puissant, beaucoup de développeurs pensent que c'est beaucoup
  71. trop puissant ou complexe pour les graphistes/intégrateurs et veulent utiliser un moteur de template alternatif.
  72. <classname>Zend_View</classname> fournit deux mécanismes pour faire cela, le premier à travers les scripts de vues, le
  73. second en implémentant <classname>Zend_View_Interface</classname>.</para>
  74. <sect3 id="zend.view.scripts.templates.scripts">
  75. <title>Système de gabarit utilisant les scripts de vues</title>
  76. <para>Un script de vue peut être utilisé pour instancier et manipuler un objet de gabarit séparé, comme un
  77. gabarit de type PHPLIB. Le script de vue pour ce type d'activité pourrait ressembler à ceci :</para>
  78. <programlisting role="php"><![CDATA[
  79. include_once 'template.inc';
  80. $tpl = new Template();
  81. if ($this->livres) {
  82. $tpl->setFile(array(
  83. "listelivre" => "listelivre.tpl",
  84. "chaquelivre" => "chaquelivre.tpl",
  85. ));
  86. foreach ($this->livres as $cle => $livre) {
  87. $tpl->set_var('auteur', $this->escape($livre['auteur']);
  88. $tpl->set_var('titre', $this->escape($livre['titre']);
  89. $tpl->parse("livre", "chaquelivre", true);
  90. }
  91. $tpl->pparse("output", "listelivre");
  92. } else {
  93. $tpl->setFile("nobooks", "pasdelivres.tpl")
  94. $tpl->pparse("output", "pasdelivres");
  95. }
  96. ]]></programlisting>
  97. <para>Et ceci pourrait être les fichiers de gabarits correspondants :</para>
  98. <programlisting role="html"><![CDATA[
  99. <!-- listelivre.tpl -->
  100. <table>
  101. <tr>
  102. <th>Auteur</th>
  103. <th>Titre</th>
  104. </tr>
  105. {livres}
  106. </table>
  107. <!-- chaquelivre.tpl -->
  108. <tr>
  109. <td>{auteur}</td>
  110. <td>{title}</td>
  111. </tr>
  112. <!-- pasdelivres.tpl -->
  113. <p>Aucun livre à afficher</p>
  114. ]]></programlisting>
  115. </sect3>
  116. <sect3 id="zend.view.scripts.templates.interface">
  117. <title>Système de gabarit utilisant Zend_View_Interface</title>
  118. <para>Certains peuvent trouver plus facile de simplement fournir un moteur de gabarit compatible avec
  119. <classname>Zend_View</classname>. <classname>Zend_View_Interface</classname> définit l'interface de compatibilité minimale
  120. nécessaire :</para>
  121. <programlisting role="php"><![CDATA[
  122. /**
  123. * Retourne l'objet moteur de gabarit actuel
  124. */
  125. public function getEngine();
  126. /**
  127. * Affecte le dossier des scripts de gabarits
  128. */
  129. public function setScriptPath($path);
  130. /**
  131. * Règle un chemin de base pour toutes les ressources de vue
  132. */
  133. public function setBasePath($path, $prefix = 'Zend_View');
  134. /**
  135. * Ajoute un chemin de base supplémentaire pour les ressources de vue
  136. */
  137. public function addBasePath($path, $prefix = 'Zend_View');
  138. /**
  139. * Récupère les chemins actuels vers les ressources de vue
  140. */
  141. public function getScriptPaths();
  142. /**
  143. * Méthode à surcharger pour affecter les variables des gabarits
  144. * en tant que propriétés de l'objet
  145. */
  146. public function __set($key, $value);
  147. public function __isset($key);
  148. public function __unset($key);
  149. /**
  150. * Affectation manuelle de variable de gabarit, ou possibilité
  151. * d'affecter des variables en masse.
  152. */
  153. public function assign($spec, $value = null);
  154. /**
  155. * Efface toutes les variables du gabarit déjà affectées
  156. */
  157. public function clearVars();
  158. /**
  159. * Effectue le rendu du gabarit nommé $name
  160. */
  161. public function render($name);
  162. ]]></programlisting>
  163. <para>En utilisant cette interface, il devient relativement facile d'encapsuler un moteur de gabarit tiers
  164. comme une classe compatible <classname>Zend_View</classname>. Comme par exemple, le code suivant est une encapsulation
  165. potentielle de Smarty :</para>
  166. <programlisting role="php"><![CDATA[
  167. class Zend_View_Smarty implements Zend_View_Interface
  168. {
  169. /**
  170. * Objet Smarty
  171. * @var Smarty
  172. */
  173. protected $_smarty;
  174. /**
  175. * Constructeur
  176. *
  177. * @param string $tmplPath
  178. * @param array $extraParams
  179. * @return void
  180. */
  181. public function __construct($tmplPath = null,
  182. $extraParams = array())
  183. {
  184. $this->_smarty = new Smarty;
  185. if (null !== $tmplPath) {
  186. $this->setScriptPath($tmplPath);
  187. }
  188. foreach ($extraParams as $key => $value) {
  189. $this->_smarty->$key = $value;
  190. }
  191. }
  192. /**
  193. * Retourne l'objet moteur de gabarit
  194. *
  195. * @return Smarty
  196. */
  197. public function getEngine()
  198. {
  199. return $this->_smarty;
  200. }
  201. /**
  202. * Affecte le dossier des scripts de gabarits
  203. *
  204. * @param string $path Le répertoire à affecter au path
  205. * @return void
  206. */
  207. public function setScriptPath($path)
  208. {
  209. if (is_readable($path)) {
  210. $this->_smarty->template_dir = $path;
  211. return;
  212. }
  213. throw new Exception('Répertoire fourni invalide');
  214. }
  215. /**
  216. * Récupère le dossier courant des gabarits
  217. *
  218. * @return string
  219. */
  220. public function getScriptPaths()
  221. {
  222. return array($this->_smarty->template_dir);
  223. }
  224. /**
  225. * Alias pour setScriptPath
  226. *
  227. * @param string $path
  228. * @param string $prefix Unused
  229. * @return void
  230. */
  231. public function setBasePath($path, $prefix = 'Zend_View')
  232. {
  233. return $this->setScriptPath($path);
  234. }
  235. /**
  236. * Alias pour setScriptPath
  237. *
  238. * @param string $path
  239. * @param string $prefix Unused
  240. * @return void
  241. */
  242. public function addBasePath($path, $prefix = 'Zend_View')
  243. {
  244. return $this->setScriptPath($path);
  245. }
  246. /**
  247. * Affectation une variable au gabarit
  248. *
  249. * @param string $key Le nom de la variable
  250. * @param mixed $val La valeur de la variable
  251. * @return void
  252. */
  253. public function __set($key, $val)
  254. {
  255. $this->_smarty->assign($key, $val);
  256. }
  257. /**
  258. * Autorise le fonctionnement du test avec empty() and isset()
  259. *
  260. * @param string $key
  261. * @return boolean
  262. */
  263. public function __isset($key)
  264. {
  265. return (null !== $this->_smarty->get_template_vars($key));
  266. }
  267. /**
  268. * Autorise l'effacement de toutes les variables du gabarit
  269. *
  270. * @param string $key
  271. * @return void
  272. */
  273. public function __unset($key)
  274. {
  275. $this->_smarty->clear_assign($key);
  276. }
  277. /**
  278. * Affectation de variables au gabarit
  279. *
  280. * Autorise une affectation simple (une clé => une valeur)
  281. * OU
  282. * le passage d'un tableau (paire de clé => valeur)
  283. * à affecter en masse
  284. *
  285. * @see __set()
  286. * @param string|array $spec Le type d'affectation à utiliser
  287. (clé ou tableau de paires clé => valeur)
  288. * @param mixed $value (Optionel) Si vous assignez une variable nommée,
  289. utilisé ceci comme valeur
  290. * @return void
  291. */
  292. public function assign($spec, $value = null)
  293. {
  294. if (is_array($spec)) {
  295. $this->_smarty->assign($spec);
  296. return;
  297. }
  298. $this->_smarty->assign($spec, $value);
  299. }
  300. /**
  301. * Effacement de toutes les variables affectées
  302. *
  303. * Efface toutes les variables affectées à Zend_View
  304. * via {@link assign()} ou surcharge de propriété
  305. * ({@link __get()}/{@link __set()}).
  306. *
  307. * @return void
  308. */
  309. public function clearVars()
  310. {
  311. $this->_smarty->clear_all_assign();
  312. }
  313. /**
  314. * Exécute le gabarit et retourne l'affichage
  315. *
  316. * @param string $name Le gabarit à exécuter
  317. * @return string L'affichage
  318. */
  319. public function render($name)
  320. {
  321. return $this->_smarty->fetch($name);
  322. }
  323. }
  324. ]]></programlisting>
  325. <para>Dans cet exemple, vous instanciez la classe <classname>Zend_View_Smarty</classname> au lieu de
  326. <classname>Zend_View</classname>, et vous l'utilisez de la même façon :</para>
  327. <programlisting role="php"><![CDATA[
  328. //Exemple 1a. Dans l'initView() de l'initializer.
  329. $view = new Zend_View_Smarty('/chemin/vers/les/templates');
  330. $viewRenderer = new Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
  331. $viewRenderer->setView($view)
  332. ->setViewBasePathSpec($view->_smarty->template_dir)
  333. ->setViewScriptPathSpec(':controller/:action.:suffix')
  334. ->setViewScriptPathNoControllerSpec(':action.:suffix')
  335. ->setViewSuffix('tpl');
  336. //Exemple 1b. L'utilisation dans le contrôleur d'action reste la même
  337. class FooController extends Zend_Controller_Action
  338. {
  339. public function barAction()
  340. {
  341. $this->view->book = 'Zend PHP 5 Certification Study Guide';
  342. $this->view->author = 'Davey Shafik and Ben Ramsey'
  343. }
  344. }
  345. //Example 2. Initialisation de la vue dans le contrôleur d'action
  346. class FooController extends Zend_Controller_Action
  347. {
  348. public function init()
  349. {
  350. $this->view = new Zend_View_Smarty('/path/to/templates');
  351. $viewRenderer = $this->_helper->getHelper('viewRenderer');
  352. $viewRenderer->setView($this->view)
  353. ->setViewBasePathSpec($view->_smarty->template_dir)
  354. ->setViewScriptPathSpec(':controller/:action.:suffix')
  355. ->setViewScriptPathNoControllerSpec(':action.:suffix')
  356. ->setViewSuffix('tpl');
  357. }
  358. }
  359. ]]></programlisting>
  360. </sect3>
  361. </sect2>
  362. </sect1>