Zend_Controller-ActionController.xml 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- EN-Revision: 15617 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.controller.action">
  5. <title>Contrôleurs d'action</title>
  6. <sect2 id="zend.controller.action.introduction">
  7. <title>Introduction</title>
  8. <para>
  9. <classname>Zend_Controller_Action</classname> est une classe abstraite que vous
  10. pouvez utiliser avec le contrôleur frontal quand vous construisez un site Web basé sur
  11. le modèle de conception Modèle-Vues-Contrôleurs (MVC).
  12. </para>
  13. <para>
  14. Pour utiliser <classname>Zend_Controller_Action</classname>, vous devez la
  15. sous-classer dans vos propres classes de contrôleurs d'action (ou la sous-classer pour
  16. créer votre propre classe de base pour vos contrôleurs d'action). L'opération la plus
  17. basique est de la sous-classer, et de créer vos méthodes d'action qui correspondent aux
  18. différentes actions que vous souhaitez gérer. La gestion du routage et de la
  19. distribution des <classname>Zend_Controller</classname> va rechercher automatiquement
  20. les méthodes dont le nom termine par 'Action' dans votre classe et les considérer comme
  21. des actions potentiellement valides de votre contrôleur.
  22. </para>
  23. <para>Par exemple, considérons une classe définie comme ceci&#160;:</para>
  24. <programlisting language="php"><![CDATA[
  25. class FooController extends Zend_Controller_Action
  26. {
  27. public function barAction()
  28. {
  29. // réalise quelquechose
  30. }
  31. public function bazAction()
  32. {
  33. // réalise quelquechose
  34. }
  35. }
  36. ]]></programlisting>
  37. <para>
  38. La classe <code>FooController</code> (contrôleur <code>foo</code>) définit deux
  39. actions, <code>bar</code> et <code>baz</code>.
  40. </para>
  41. <para>
  42. Il y a d'autres fonctionnalités qui peuvent être utilisées, comme personnaliser
  43. l'initialisation des actions, gérer les actions par défaut quand aucune action ou une
  44. action invalide est fournie, avoir la possibilité de hook ("détournement") en pre et
  45. post-dispatch, et une variété de méthodes d'aides (helper). Ce chapitre fournit une vue
  46. d'ensemble des fonctionnalités du contrôleur d'action.
  47. </para>
  48. <note>
  49. <title>Comportement par défaut</title>
  50. <para>
  51. Par défaut, le <link linkend="zend.controller.front">contrôleur frontal</link>
  52. active l'aide d'action
  53. <link linkend="zend.controller.actionhelpers.viewrenderer">ViewRenderer</link>.
  54. Cette aide s'occupe de l'injection automatique de l'objet de vue dans vos
  55. contrôleurs, ainsi que du rendu de cette vue. Vous pouvez la désactiver au sein de
  56. vos contrôleurs par l'une ou l'autre des actions suivantes&#160;:
  57. </para>
  58. <programlisting language="php"><![CDATA[
  59. class FooController extends Zend_Controller_Action
  60. {
  61. public function init()
  62. {
  63. // Locale à ce seul contrôleur ; affecte toutes les actions,
  64. // si chargée dans l'init :
  65. $this->_helper->viewRenderer->setNoRender(true);
  66. // Global :
  67. $this->_helper->removeHelper('viewRenderer');
  68. // Global aussi, mais doit être réalisé en conjonction avec
  69. // la version locale pour être propagé dans ce contrôleur:
  70. Zend_Controller_Front::getInstance()->setParam('noViewRenderer',
  71. true);
  72. }
  73. }
  74. ]]></programlisting>
  75. <para>
  76. Les méthodes <code>initView()</code>, <code>getViewScript()</code>,
  77. <code>render()</code>, et <code>renderScript()</code> sont affectées chacune au
  78. <code>ViewRenderer</code> à moins que l'aide ne soit pas chargée dans le
  79. gestionnaire d'aide (helper broker) ou que l'option <code>noViewRenderer</code>
  80. n'ait été réglée.
  81. </para>
  82. <para>
  83. Vous pouvez simplement désactiver le rendu pour une vue individuelle grâce à
  84. la méthode <code>noRender()</code> du <code>ViewRenderer</code>&#160;:
  85. </para>
  86. <programlisting language="php"><![CDATA[
  87. class FooController extends Zend_Controller_Action
  88. {
  89. public function barAction()
  90. {
  91. // désactive le rendu automatique pour cette action seulement :
  92. $this->_helper->viewRenderer->setNoRender();
  93. }
  94. }
  95. ]]></programlisting>
  96. <para>
  97. Les raisons principales de désactiver le <code>ViewRenderer</code> sont
  98. l'absence de besoin d'objets de vues ou si vous n'effectuez pas de rendu via des
  99. scripts de vues (par exemple, quand vous utilisez un contrôleur d'action pour
  100. servir des protocoles de service Web comme SOAP, XML-RPC ou REST). Dans la plupart
  101. des cas, il n'est pas nécessaire de désactiver globalement le
  102. <code>ViewRenderer</code>, seulement de manière sélective pour des contrôleurs ou
  103. actions individuels.
  104. </para>
  105. </note>
  106. </sect2>
  107. <sect2 id="zend.controller.action.initialization">
  108. <title>Initialisation d'objet</title>
  109. <para>
  110. Même si vous pouvez toujours surcharger le constructeur du contrôleur d'action,
  111. nous ne vous le recommandons pas.
  112. <classname>Zend_Controller_Action::__construct()</classname> réalise certaines tâches
  113. importantes, comme l'enregistrement des objets de requêtes et de réponses, ainsi que
  114. l'invocation d'arguments personnalisés fourni par le contrôleur frontal. Si vous devez
  115. surcharger le constructeur, n'oubliez pas d'appeler
  116. <code>parent::__construct($request, $response, $invokeArgs)</code>.
  117. </para>
  118. <para>
  119. La manière la plus appropriée de personnaliser l'instanciation est d'utiliser la
  120. méthode <code>init()</code>, qui est appelée en dernière tâche de
  121. <code>__construct()</code>. Par exemple, si vous voulez vous connecter à une base de
  122. données à l'instanciation&#160;:
  123. </para>
  124. <programlisting language="php"><![CDATA[
  125. class FooController extends Zend_Controller_Action
  126. {
  127. public function init()
  128. {
  129. $this->db = Zend_Db::factory('Pdo_Mysql', array(
  130. 'host' => 'myhost',
  131. 'username' => 'user',
  132. 'password' => 'XXXXXXX',
  133. 'dbname' => 'website'
  134. ));
  135. }
  136. }
  137. ]]></programlisting>
  138. </sect2>
  139. <sect2 id="zend.controller.action.prepostdispatch">
  140. <title>Détournement Pre et Post-Dispatch (Hook)</title>
  141. <para>
  142. <classname>Zend_Controller_Action</classname> spécifie deux méthodes qui peuvent
  143. être appelées juste avant et juste après une action, <code>preDispatch()</code> et
  144. <code>postDispatch()</code>. Celles-ci peuvent être pratiques dans plusieurs cas&#160;:
  145. vérifier l'authentification et les ACL avant d'exécuter une action (en appelant
  146. <code>_forward()</code> dans <code>preDispatch()</code>, l'action sera évitée), par
  147. exemple, ou en plaçant du contenu généré dans une partie du modèle du site
  148. (<code>postDispatch()</code>).
  149. </para>
  150. </sect2>
  151. <sect2 id="zend.controller.action.accessors">
  152. <title>Accesseurs</title>
  153. <para>
  154. Un certain nombre d'objets et de variables sont enregistrés avec l'objet et chacun
  155. possède des méthodes accesseurs.
  156. </para>
  157. <itemizedlist>
  158. <listitem>
  159. <para>
  160. <emphasis>Objet Requête</emphasis>&#160;: <code>getRequest()</code> peut être
  161. utilisé pour récupérer l'objet de requête utilisé pour appeler l'action.
  162. </para>
  163. </listitem>
  164. <listitem>
  165. <para>
  166. <emphasis>Objet Réponse</emphasis>&#160;: <code>getResponse()</code> peut être
  167. utilisé pour récupérer l'objet de réponse assemblant la réponse finale.
  168. Quelques appels typiques peuvent ressembler à ceci :
  169. </para>
  170. <programlisting language="php"><![CDATA[
  171. $this->getResponse()->setHeader('Content-Type', 'text/xml');
  172. $this->getResponse()->appendBody($content);
  173. ]]></programlisting>
  174. </listitem>
  175. <listitem>
  176. <para>
  177. <emphasis>Arguments d'invocation</emphasis>&#160;: le contrôleur frontal peut
  178. transmettre des paramètres au routeur, au distributeur, et au contrôleur
  179. d'action. Pour récupérer individuellement ceux-ci utilisez
  180. <code>getInvokeArg($key)</code> ; alternativement, récupérer la liste entière
  181. en utilisant <code>getInvokeArgs()</code>.
  182. </para>
  183. </listitem>
  184. <listitem>
  185. <para>
  186. <emphasis>Paramètres de requêtes</emphasis>&#160;: l'objet de requête
  187. rassemble les paramètres de requête, comme les paramètres _GET ou _POST, ou les
  188. paramètres utilisateurs spécifiés dans le chemin d'URL. Pour récupérer ceux-ci
  189. utilisez <code>_getParam($key)</code> ou <code>_getAllParams()</code>. Vous
  190. pouvez aussi régler ces paramètres en utilisant <code>_setParam()</code>&#160;;
  191. ceci est pratique quand vous redirigez vers des actions additionnelles.
  192. </para>
  193. <para>
  194. Pour tester si un paramètre existe ou non (pratique pour les branchements
  195. logiques), utilisez <code>_hasParam($key)</code>.
  196. </para>
  197. <note>
  198. <para>
  199. <code>_getParam()</code> peut prendre un second paramètre optionnel
  200. contenant une valeur par défaut à utiliser si le paramètre n'est pas réglé
  201. ou qu'il est vide. Utiliser ceci élimine la nécessité d'appeler
  202. <code>_hasParam()</code> avant de récupérer une valeur&#160;:
  203. </para>
  204. <programlisting language="php"><![CDATA[
  205. // Utilise une valeur par défaut de 1 si id n'est pas réglé
  206. $id = $this->_getParam('id', 1);
  207. // Au lieu de :
  208. if ($this->_hasParam('id') {
  209. $id = $this->_getParam('id');
  210. } else {
  211. $id = 1;
  212. }
  213. ]]></programlisting>
  214. </note>
  215. </listitem>
  216. </itemizedlist>
  217. </sect2>
  218. <sect2 id="zend.controller.action.viewintegration">
  219. <title>Intégration des Vues</title>
  220. <para>
  221. <classname>Zend_Controller_Action</classname> fournit un mécanisme rudimentaire
  222. et flexible pour l'intégration des vues. Deux méthodes accomplissent ceci,
  223. <code>initView()</code> et <code>render()</code>&#160;; la première méthode charge la
  224. propriété publique <code>$view</code>, et la dernière effectue le rendu d'une vue basé
  225. sur l'action courante demandée dans la requête, en utilisant la hiérarchie des
  226. répertoires pour déterminer le chemin du script.
  227. </para>
  228. <sect3 id="zend.controller.action.viewintegration.initview">
  229. <title>Initialisation des Vues</title>
  230. <note id="zend.controller.action.viewintegration.viewrenderer">
  231. <title>
  232. Par défaut, l'intégration des vues est réalisé via le ViewRenderer
  233. </title>
  234. <para>
  235. Le contenu de cette section n'est valable que si vous avez explicitement
  236. désactivé le
  237. <link linkend="zend.controller.actionhelpers.viewrenderer">ViewRenderer</link>.
  238. Sinon, vous pouvez passer à la section suivante.
  239. </para>
  240. </note>
  241. <para>
  242. <code>initView()</code> initialise l'objet Vue. <code>render()</code> appelle
  243. <code>initView()</code> dans le but de récupérer l'objet de vue, mais il peut être
  244. initialisé à tout moment&#160;; par défaut il remplit la propriété
  245. <code>$view</code> avec un objet <classname>Zend_View</classname>, mais toute
  246. classe implémentant <classname>Zend_View_Interface</classname> peut être utilisée.
  247. Si <code>$view</code> est déjà initialisé, il retourne simplement cette
  248. propriété.
  249. </para>
  250. <para>
  251. La mise en oeuvre par défaut suppose la structure de répertoire suivante&#160;:
  252. </para>
  253. <programlisting language="php"><![CDATA[
  254. applicationOrModule/
  255. controllers/
  256. IndexController.php
  257. views/
  258. scripts/
  259. index/
  260. index.phtml
  261. helpers/
  262. filters/
  263. ]]></programlisting>
  264. <para>
  265. En d'autres termes, les scripts de vues sont supposés être dans le
  266. sous-répertoire <code>views/scripts/</code>, et le sous-répertoire
  267. <code>views</code> est censé contenir les fonctionnalités soeurs (aides [helpers],
  268. filtres [filters]). En déterminant le script de vue et son chemin, le répertoire
  269. <code>views/scripts/</code> est utilisé comme chemin de base, avec des dossiers
  270. nommés par le nom de contrôleur fournissant ainsi la hiérarchie des scripts de
  271. vues.
  272. </para>
  273. </sect3>
  274. <sect3 id="zend.controller.action.viewintegration.render">
  275. <title>Effectuer le rendu des Vues</title>
  276. <para><code>render()</code> a la signature suivante&#160;:</para>
  277. <programlisting language="php"><![CDATA[
  278. string render(string $action = null,
  279. string $name = null,
  280. bool $noController = false);
  281. ]]></programlisting>
  282. <para>
  283. <code>render()</code> effectue le rendu d'un script de vue. Si aucun argument
  284. n'est fourni, la méthode suppose que le script requêté est
  285. <code>[controller]/[action].phtml</code> (où <code>.phtml</code> est la valeur de
  286. la propriété <code>$viewSuffix</code>). Fournir une valeur pour
  287. <code>$action</code> va effectuer le rendu du script dans le sous-dossier
  288. <code>[controller]</code>. Pour surcharger l'utilisation du sous-dossier
  289. <code>[controller]</code>, fournissez la valeur <code>true</code> à
  290. <code>$noController</code>. Enfin, les scripts sont rendus dans l'objet
  291. réponse&#160;; si vous souhaitez effectuer le rendu dans un
  292. <link linkend="zend.controller.response.namedsegments">segment
  293. nommé</link>spécifique de l'objet réponse, fournissez une valeur à
  294. <code>$name</code>.
  295. </para>
  296. <note>
  297. <para>
  298. Puisque le contrôleur et des noms d'action peuvent contenir des
  299. caractères délimiteurs de mot comme '_', '.' et '-', <code>render()</code>
  300. normalise ceux-ci à '-' en déterminant le nom du script. En interne, il utilise
  301. le délimiteur de mot et de chemin du distributeur pour faire cette
  302. normalisation. Ainsi, une requête pour <code>/foo.bar/baz-bat</code> rendra le
  303. script <code>foo-bar/baz-bat.phtml</code>. Si votre méthode d'action contient
  304. des notationsCamel, veuillez vous souvenir que ceci va résulter avec des mots
  305. séparés par '-' en déterminant le nom de fichier du script de vue.
  306. </para>
  307. </note>
  308. <para>Quelques exemples :</para>
  309. <programlisting language="php"><![CDATA[
  310. class MonController extends Zend_Controller_Action
  311. {
  312. public function fooAction()
  313. {
  314. // Effectue le rendu de mon/foo.phtml
  315. $this->render();
  316. // Effectue le rendu de mon/bar.phtml
  317. $this->render('bar');
  318. // Effectue le rendu de baz.phtml
  319. $this->render('baz', null, true);
  320. // Effectue le rendu de mon/login.phtml vers le segment
  321. // 'form' de l'objet réponse
  322. $this->render('login', 'form');
  323. // Effectue le rendu de site.phtml vers le segment
  324. // 'page' de l'objet réponse ; sans utiliser
  325. // le sous-dossier 'mon/'
  326. $this->render('site', 'page', true);
  327. }
  328. public function bazBatAction()
  329. {
  330. // Effectue le rendu de mon/baz-bat.phtml
  331. $this->render();
  332. }
  333. }
  334. ]]></programlisting>
  335. </sect3>
  336. </sect2>
  337. <sect2 id="zend.controller.action.utilmethods">
  338. <title>Méthodes utiles</title>
  339. <para>
  340. En plus de l'accesseur et des méthodes d'intégration de vue,
  341. <code>Zend_Controller_Action</code> possède plusieurs méthodes utiles pour exécuter
  342. des tâches communes de l'intérieur de vos méthodes d'action (ou de
  343. pre-/post-dispatch).
  344. </para>
  345. <itemizedlist>
  346. <listitem>
  347. <para>
  348. <code>_forward($action, $controller = null, $module = null, array $params
  349. = null)</code>&#160;: exécute une autre action. Si appelé dans
  350. <code>preDispatch()</code>, la requête courante est évitée en faveur de la
  351. nouvelle. Sinon, après que l'action courante ait été exécutée, l'action
  352. demandée dans <code>_forward()</code> sera exécutée à son tour.
  353. </para>
  354. </listitem>
  355. <listitem>
  356. <para>
  357. <code>_redirect($url, array $options = array())</code>&#160;: redirige vers
  358. une autre page. Cette méthode prend un URL et un jeu d'options optionnel. Par
  359. défaut, il exécute une redirection de type HTTP 302.
  360. </para>
  361. <para>Les options peuvent inclure une ou plusieurs des clés suivantes :</para>
  362. <itemizedlist>
  363. <listitem>
  364. <para>
  365. <emphasis></emphasis>&#160;: avec ou sans sortie immédiate. Si
  366. appelée, la méthode fermera proprement toute session ouverte et
  367. réalisera la redirection.
  368. </para>
  369. <para>
  370. Vous pouvez régler cette option de manière globale dans le
  371. contrôleur en utilisant l'accesseur
  372. <code>setRedirectExit()</code>.
  373. </para>
  374. </listitem>
  375. <listitem>
  376. <para>
  377. <emphasis>prependBase</emphasis>&#160;: ajoute ou non l'URL de base
  378. enregistré dans l'objet requête à l'URL produit.
  379. </para>
  380. <para>
  381. Vous pouvez régler cette option de manière globale dans le
  382. contrôleur en utilisant l'accesseur
  383. <code>setRedirectPrependBase()</code>.
  384. </para>
  385. </listitem>
  386. <listitem>
  387. <para>
  388. <emphasis>code</emphasis>&#160;: fournit le code HTTP à utiliser pour
  389. la redirection. Par défaut, un HTTP 302 est utilisé ; tout code compris
  390. entre 301 et 306 peut être utilisé.
  391. </para>
  392. <para>
  393. Vous pouvez régler cette option de manière globale dans le
  394. contrôleur en utilisant l'accesseur
  395. <code>setRedirectCode()</code>.
  396. </para>
  397. </listitem>
  398. </itemizedlist>
  399. </listitem>
  400. </itemizedlist>
  401. </sect2>
  402. <sect2 id="zend.controller.action.subclassing">
  403. <title>Sous-classer le contrôleur d'action</title>
  404. <para>
  405. Par conception, <classname>Zend_Controller_Action</classname> doit être
  406. sous-classé pour créer un contrôleur d'action. Au minimum, vous devez définir les
  407. méthodes d'action que le contrôleur d'action peut appeler.
  408. </para>
  409. <para>
  410. En plus de la création de fonctionnalité utile pour vos applications Web, vous
  411. pouvez aussi constater que vous répétez souvent la même installation ou les mêmes
  412. méthodes utilitaires dans vos contrôleurs divers ; s'il en est ainsi, créer une classe
  413. de contrôleur de base commune qui étend <classname>Zend_Controller_Action</classname>
  414. peut résoudre une telle redondance.
  415. </para>
  416. <example id="zend.controller.action.subclassing.example-call">
  417. <title>Comment gérer des actions non-existantes</title>
  418. <para>
  419. Si une requête vers un contrôleur est faite en incluant une méthode d'action
  420. indéfinie, <classname>Zend_Controller_Action::__call()</classname> sera invoqué.
  421. <code>__call()</code> est, bien sûr, la méthode magique de PHP pour la surcharge de
  422. méthode.
  423. </para>
  424. <para>
  425. Par défaut, cette méthode lève une
  426. <classname>Zend_Controller_Action_Exception</classname> indiquant que la méthode
  427. requêtée n'a pas été trouvée dans le contrôleur. Si la méthode requêtée se termine
  428. par "Action", on considère qu'une action était requêté et qu'elle n'existe pas ; un
  429. telle erreur entraîne une exception ayant un code 404. Tout autre appel de méthode
  430. entraîne une exception ayant un code 500. Ceci vous permet de facilement
  431. différencier une page inconnue et une erreur de l'application dans votre
  432. gestionnaire d'erreur.
  433. </para>
  434. <para>
  435. Vous pouvez surcharger cette fonctionnalité si vous souhaitez exécuter
  436. d'autres opérations. Par exemple, si vous souhaitez afficher un message d'erreur,
  437. vous pouvez écrire quelque chose comme ceci&#160;:
  438. </para>
  439. <programlisting language="php"><![CDATA[
  440. class MonController extends Zend_Controller_Action
  441. {
  442. public function __call($method, $args)
  443. {
  444. if ('Action' == substr($method, -6)) {
  445. // Si une méthode d'action n'est pas trouvée,
  446. // rendre le script d'erreur
  447. return $this->render('error');
  448. }
  449. // pour toute autre méthode, levée d'une exception
  450. throw new Exception('Méthode invalide "' . $method . '" appelée',
  451. 500);
  452. }
  453. }
  454. ]]></programlisting>
  455. <para>
  456. Une autre possibilité est de rediriger vers une page de contrôleur par
  457. défaut&#160;:
  458. </para>
  459. <programlisting language="php"><![CDATA[
  460. class MyController extends Zend_Controller_Action
  461. {
  462. public function indexAction()
  463. {
  464. $this->render();
  465. }
  466. public function __call($method, $args)
  467. {
  468. if ('Action' == substr($method, -6)) {
  469. // Si une méthode d'action n'est pas trouvée,
  470. // rediriger vers l'action index
  471. return $this->_forward('index');
  472. }
  473. // pour tout autre méthode, levée d'une exception
  474. throw new Exception('Méthode invalide "' . $method . '" appelée',
  475. 500);
  476. }
  477. }
  478. ]]></programlisting>
  479. </example>
  480. <para>
  481. En plus de la surcharge de <code>__call()</code>, chacune des méthodes
  482. d'initialisation , utilitaires, d'accesseurs, de vues et de détournement de la
  483. distribution mentionnées ci-dessus peuvent être surchargées dans le but de
  484. personnaliser vos contrôleurs. Par exemple, si vous stockez votre objet de vue dans le
  485. registre, vous pouvez vouloir modifier votre méthode <code>initView()</code> avec une
  486. code comme celui-ci&#160;:
  487. </para>
  488. <programlisting language="php"><![CDATA[
  489. abstract class Ma_Base_Controller extends Zend_Controller_Action
  490. {
  491. public function initView()
  492. {
  493. if (null === $this->view) {
  494. if (Zend_Registry::isRegistered('view')) {
  495. $this->view = Zend_Registry::get('view');
  496. } else {
  497. $this->view = new Zend_View();
  498. $this->view->setBasePath(dirname(__FILE__) . '/../views');
  499. }
  500. }
  501. return $this->view;
  502. }
  503. }
  504. ]]></programlisting>
  505. <para>
  506. En espérant que les informations de ce chapitre vous permettent de voir la
  507. flexibilité de ce composant particulier et comment vous pouvez le modifier suivant les
  508. besoins de votre application.
  509. </para>
  510. </sect2>
  511. </sect1>