1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- EN-Revision: 22189 -->
4 <sect1 id="learning.view.placeholders.standard">
5 <title>Placeholders standards</title>
8 Dans la <link linkend="learning.view.placeholders.basics">section précédente</link>, nous
9 avons vu l'aide de vue <methodname>placeholder()</methodname> et comment l'utiliser pour
10 aggréger du contenu personnalisable. Dans ce chapitre, nous allons passer en revue quelques
11 placeholders concrets fournis avec Zend Framework, ainsi que la manière de les utiliser à
12 votre avantage pour créer des layouts complexes.
16 La plupart des placeholders fournis permettent de gérer le contenur de la section
17 <emphasis><head></emphasis> de la layout -- une zone qui ne peut typiquement pas être
18 manipulée directement par vos scripts de vue, mais que vous voulez tout de même traiter.
19 Par exemples: vous voudriez que votre titre se compose d'un certain contenu sur toutes les
20 pages mais aussi d'une partie dynamique relative au contrôleur/action en cours; aussi vous
21 voudriez préciser des fichiers <acronym>CSS</acronym> à charger basés sur la section de
22 l'application en cours; enfin vous pourriez avoir recours à des scripts JavaScript spécifiques
23 parfois, ou encore changer la déclaration de <acronym>DocType</acronym>.
27 Zend Framework est livré avec des implémentations de placeholder pour chacune de ces situations
31 <sect2 id="learning.view.placeholders.standard.doctype">
32 <title>Changer le DocType</title>
35 Les déclarations de <acronym>DocType</acronym> sont difficiles à mémoriser et souvent
36 essentielles pour s'assurer que le navigateur rende correctement le contenu. L'aide de vue
37 <methodname>doctype()</methodname> permet d'utiliser des mnemonics pour spécifier un
38 <acronym>DocType</acronym>; aussi, d'autres aides de vues interrogeront l'aide
39 <methodname>doctype()</methodname> pour s'assurer que le contenu qu'elles génèrent est
40 conforme au <acronym>DocType</acronym> utilisé.
44 Par exemple si vous souhaitez utiliser la <acronym>DTD</acronym>
45 <acronym>XHTML1</acronym> Strict, vous pouvez simplement la préciser
49 <programlisting language="php"><![CDATA[
50 $this->doctype('XHTML1_STRICT');
54 Voici les autres mnemonics utilisables:
59 <term>XHTML1_STRICT</term>
63 <acronym>XHTML</acronym> 1.0 Strict
69 <term>XHTML1_TRANSITIONAL</term>
73 <acronym>XHTML</acronym> 1.0 Transitional
79 <term>HTML4_STRICT</term>
83 <acronym>HTML</acronym> 4.01 Strict
89 <term>HTML4_Loose</term>
93 <acronym>HTML</acronym> 4.01 Loose
103 <acronym>HTML</acronym> 5
110 Vous pouvez changer le type et rendre la déclaration en un seul appel:
113 <programlisting language="php"><![CDATA[
114 echo $this->doctype('XHTML1_STRICT');
118 Cependant l'approche conseillée est de préciser le type dans le bootstrap et rendre l'aide
119 de vue dans la layout. Essayez d'ajouter ceci à votre classe de bootstrap:
122 <programlisting language="php"><![CDATA[
123 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
125 protected function _initDocType()
127 $this->bootstrap('View');
128 $view = $this->getResource('View');
129 $view->doctype('XHTML1_STRICT');
135 Puis, dans le script de layout, affichez simplement avec <function>echo</function> l'aide en
139 <programlisting language="php"><![CDATA[
140 <?php echo $this->doctype() ?>
146 Ceci permet d'être sûr que les aides de vue diverses utiliseront cette déclaration,
147 que le docType est précisé avant le rendu du layout et qu'il n'existe qu'un seul endroit
148 logique pour le changer.
152 <sect2 id="learning.view.placeholders.standard.head-title">
153 <title>Spécifier le titre de la page</title>
156 Souvent, le site incluera le nom de la société dans le titre de la page et ajoutera
157 ensuite des informations basées sur la page en cours de lecture. Par exemple, le site
158 zend.com inclut la chaine "Zend.com" sur toutes les pages et y fait précèder des
159 informations relatives à la page en cours: "Zend Server - Zend.com". Dans Zend Framework,
160 l'aide de vue <methodname>headTitle()</methodname> peut vous simplifier cette tâche.
164 Au plus simple, l'aide <methodname>headTitle()</methodname> permet d'aggréger du contenu
165 pour la balise <emphasis><title></emphasis>; lorsque vous l'affichez, il assemble
166 son contenu dans l'ordre des ajouts. Pour contrôler l'ordre, les méthodes
167 <methodname>prepend()</methodname> et <methodname>append()</methodname> sont là, pour changer
168 le séparateur à utiliser entre les segments, utilisez la méthode
169 <methodname>setSeparator()</methodname>.
173 Typiquement vous devriez renseigner tous les segments communs à toutes les pages en bootstrap,
174 de la même manière que nous avions agit avec le doctype. Dans ce cas, nous allons écrire une
175 méthode <methodname>_initPlaceholders()</methodname> pour gérer tous les placeholders et préciser
176 un titre initial ainsi qu'un séparateur.
179 <programlisting language="php"><![CDATA[
180 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
184 protected function _initPlaceholders()
186 $this->bootstrap('View');
187 $view = $this->getResource('View');
188 $view->doctype('XHTML1_STRICT');
190 // Précise le titre initial et le séparateur:
191 $view->headTitle('My Site')
192 ->setSeparator(' :: ');
200 Dans un script de vue, nous voulons ajouter un nouveau segment:
203 <programlisting language="php"><![CDATA[
204 <?php $this->headTitle()->append('Some Page'); // placé après les autres segments ?>
205 <?php $this->headTitle()->prepend('Some Page'); // placé avant ?>
209 Dans notre layout, nous affichons simplement l'aide <methodname>headTitle()</methodname>:
212 <programlisting language="php"><![CDATA[
213 <?php echo $this->doctype() ?>
215 <?php echo $this->headTitle() ?>
220 Le contenu suivant aura été généré:
223 <programlisting language="html"><![CDATA[
224 <!-- Si append() a été utilisé: -->
225 <title>My Site :: Some Page</title>
227 <!-- Si prepend() a été utilisé: -->
228 <title>Some Page :: My Site</title>
232 <sect2 id="learning.view.placeholders.standard.head-link">
233 <title>Spécifier des feuilles de style avec HeadLink</title>
236 Les bons développeurs <acronym>CSS</acronym> créront souvent une feuille de style
237 globale et des feuilles individuelles pour les sections spécifiques ou certaines pages
238 du site puis chargeront celles-ci plus tard conditionnellement afin de réduire
239 le nombre de données à transférer entre chaque requête. Le placeholder
240 <methodname>headLink()</methodname> permet de réaliser de telles aggrégations
241 conditionnelles de feuilles de style.
245 Pour cela, <methodname>headLink()</methodname> definit une certain nombre de méthodes
246 "virtuelles" (via surcharge) pour simplifier le tout. Celles qui vont nous concernet
247 sont <methodname>appendStylesheet()</methodname> et
248 <methodname>prependStylesheet()</methodname>. Chacune peut accepter jusqu'à quatre
249 arguments, <varname>$href</varname> (chemin relatif vers la feuille de style),
250 <varname>$media</varname> (le type <acronym>MIME</acronym>, par défaut "text/css"),
251 <varname>$conditionalStylesheet</varname> (à utiliser pour préciser une "condition"
252 à évaluer pour la feuille de style), et <varname>$extras</varname> (un tableau
253 associatif utiliser générallement pour renseigner une clé pour "media"). Dans la
254 plupart des cas, seul le premier argument suffira, le chemin relatif vers la feuille
259 Dans notre exemple, nous supposerons que toutes les pages ont besoin de charger une feuille
260 de style stockée dans "<filename>/styles/site.css</filename>" (relativement au document root);
261 nous allons préciser cela dans notre méthode de bootstrap
262 <methodname>_initPlaceholders()</methodname>.
265 <programlisting language="php"><![CDATA[
266 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
270 protected function _initPlaceholders()
272 $this->bootstrap('View');
273 $view = $this->getResource('View');
274 $view->doctype('XHTML1_STRICT');
276 // Affecte le titre original et le séparateur:
277 $view->headTitle('My Site')
278 ->setSeparator(' :: ');
280 // Affecte la feuille de style originale:
281 $view->headLink()->prependStylesheet('/styles/site.css');
289 Plus tard, dans un contrôleur par exemple, nous pouvons rajouter des feuilles de
293 <programlisting language="php"><![CDATA[
294 <?php $this->headLink()->appendStylesheet('/styles/user-list.css') ?>
298 Dans notre layout, là encore, un simple echo sur le placeholer:
301 <programlisting language="php"><![CDATA[
302 <?php echo $this->doctype() ?>
304 <?php echo $this->headTitle() ?>
305 <?php echo $this->headLink() ?>
310 Ceci génèrera quelque chose comme:
313 <programlisting language="html"><![CDATA[
314 <link rel="stylesheet" type="text/css" href="/styles/site.css" />
315 <link rel="stylesheet" type="text/css" href="/styles/user-list.css" />
319 <sect2 id="learning.view.placeholders.standard.head-script">
320 <title>Aggréger des scripts avec HeadScript</title>
323 Un autre moyen de ne pas surcharger la page est de ne charger le JavaScript que lorsque
324 c'est nécessaire. Vous aurez donc besoin de scripts découpés: peut-être un pour afficher
325 le menu du site progressivement, un autre pour traiter le contenu d'une page spécifique.
326 Dans ces cas, l'aide <methodname>headScript()</methodname> propose une solution.
330 Comme l'aide <methodname>headLink()</methodname>, <methodname>headScript()</methodname>
331 permet d'empiler en début ou fin des scripts entiers et de les afficher d'un coup. Cela
332 est très flexible pour spécifier des fichiers de scripts entiers à charger, ou encore
333 du code JavaScript explicite. Vous pouvez aussi capturer le JavaScript via
334 <methodname>captureStart()</methodname>/<methodname>captureEnd()</methodname>, qui
335 permettent d'utiliser du code JavaScript inline plutot que de demander un appel serveur
336 pour charger un fichier.
340 Tout comme <methodname>headLink()</methodname>, <methodname>headScript()</methodname>
341 propose des mééthodes "virtuelles" via surcharge pour spécifier rapidement des contenus
342 à aggréger; les méthodes sont <methodname>prependFile()</methodname>,
343 <methodname>appendFile()</methodname>, <methodname>prependScript()</methodname>, et
344 <methodname>appendScript()</methodname>. Les deux premières vous permettent de préciser
345 des fichiers référéncés dans l'attribut <varname>$src</varname> d'une balise
346 <emphasis><script></emphasis>; les deux dernières vont prendre le contenu qu'on leur
347 passe et le rendre comme du JavaScript dans les balises <emphasis><script></emphasis>.
351 Dans cet exemple, nous allons spécifier qu'un script, "<filename>/js/site.js</filename>" a
352 besoin d'être chargé sur chaque page; nous allons donc mettre à jour notre méthode de
353 bootstap <methodname>_initPlaceholders()</methodname> pour effectuer cela.
356 <programlisting language="php"><![CDATA[
357 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
361 protected function _initPlaceholders()
363 $this->bootstrap('View');
364 $view = $this->getResource('View');
365 $view->doctype('XHTML1_STRICT');
367 // Titre et séparateur d'origine:
368 $view->headTitle('My Site')
369 ->setSeparator(' :: ');
371 // Feuille de style originale:
372 $view->headLink()->prependStylesheet('/styles/site.css');
374 // Affecte le JS initial à charger:
375 $view->headScript()->prependFile('/js/site.js');
383 Dans un script de vue, nous voulons ajouter un script ou capturer du contenu JavaScript
384 à inclure dans le document.
387 <programlisting language="php"><![CDATA[
388 <?php $this->headScript()->appendFile('/js/user-list.js') ?>
389 <?php $this->headScript()->captureStart() ?>
391 baseUrl: "<?php echo $this->baseUrl() ?>"
393 <?php $this->headScript()->captureEnd() ?>
397 Dans notre script de layout, nous affichons simplement le placeholder, tout comme nous avions
398 fait pour les autres précédemment:
401 <programlisting language="php"><![CDATA[
402 <?php echo $this->doctype() ?>
404 <?php echo $this->headTitle() ?>
405 <?php echo $this->headLink() ?>
406 <?php echo $this->headScript() ?>
411 Le contenu suivant sera généré:
414 <programlisting language="html"><![CDATA[
415 <script type="text/javascript" src="/js/site.js"></script>
416 <script type="text/javascript" src="/js/user-list.js"></script>
417 <script type="text/javascript">
419 baseUrl: "<?php echo $this->baseUrl() ?>"
425 <title>Variante InlineScript</title>
428 La plupart des navigateur bloquent l'affichage tant que tous les scritps et les feuilles
429 de style référencés dans la section <emphasis><head></emphasis> ne sont pas chargés.
430 Ces règles permettent un meilleur feeling au niveau du rendu de la page et permettent
431 à l'utilisateur de voir le contenu de la page plus tôt.
435 Pour cela, vous pouvez par exemple écrire vos tags <emphasis><script></emphasis>
436 après avoir fermé <emphasis><body></emphasis>. (C'est une pratique recommandée
437 par <ulink url="http://developer.yahoo.com/yslow/">Y! Slow project</ulink>.)
441 Zend Framework supporte cela de deux manières différentes:
447 Vous pouvez rendre <methodname>headScript()</methodname> où vous voulez dans votre
448 layout; ce n'est pas parce que la méthode commence par "head" que vous devez
449 l'appeler pour cette section du HTML.
455 Aussi, vous pourriez utiliser l'aide de vue <methodname>inlineScript()</methodname>,
456 qui est simplement une variante de <methodname>headScript()</methodname> avec le même
457 comportement mais un registre séparé.