Zend_View-Scripts.xml 14 KB

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