Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

index.html 42KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747
  1. <!doctype html>
  2. <html lang=fr>
  3. <head>
  4. <!-- Always define the charset before the title -->
  5. <meta charset=utf-8>
  6. <title>Le langage de template Django : Pour les auteurs de templates — Biologeek — David Larlet</title>
  7. <!-- Define a viewport to mobile devices to use - telling the browser to assume that the page is as wide as the device (width=device-width) and setting the initial page zoom level to be 1 (initial-scale=1.0) -->
  8. <meta name="viewport" content="width=device-width, initial-scale=1"/>
  9. <!-- Fake favicon, to avoid extra request to the server -->
  10. <link rel="icon" href="data:;base64,iVBORw0KGgo=">
  11. <link type="application/atom+xml" rel="alternate" title="Feed" href="/david/log/" />
  12. <link rel="manifest" href="/manifest.json">
  13. <link rel="stylesheet" href="/static/david/css/larlet-david-_J6Rv.css" data-instant-track />
  14. <noscript>
  15. <style type="text/css">
  16. /* Otherwise fonts are loaded by JS for faster initial rendering. See scripts at the bottom. */
  17. body {
  18. font-family: 'EquityTextB', serif;
  19. }
  20. h1, h2, h3, h4, h5, h6, time, nav a, nav a:link, nav a:visited {
  21. font-family: 'EquityCapsB', sans-serif;
  22. font-variant: normal;
  23. }
  24. </style>
  25. </noscript>
  26. <!-- Canonical URL for SEO purposes -->
  27. <link rel="canonical" href="https://larlet.fr/david/biologeek/archives/20060815-le-langage-de-template-django-pour-les-auteurs-de-templates">
  28. </head>
  29. <body>
  30. <div>
  31. <header>
  32. <nav>
  33. <p>
  34. <small>
  35. Je suis <a href="/david/" title="Profil public">David Larlet</a>, <a href="/david/pro/" title="Activité professionnelle">artisan</a> du web qui vous <a href="/david/pro/accompagnement/" title="Activité d’accompagnement">accompagne</a><span class="more-infos"> dans l’acquisition de savoirs pour concevoir des <a href="/david/pro/produits-essentiels/" title="Qu’est-ce qu’un produit essentiel ?">produits essentiels</a></span>. <span class="more-more-infos">Discutons ensemble d’une <a href="/david/pro/devis/" title="En savoir plus">non-demande de devis</a>.</span> Je partage ici mes <a href="/david/blog/" title="Expériences bienveillantes">réflexions</a> et <a href="/david/correspondances/2017/" title="Lettres hebdomadaires">correspondances</a>.
  36. </small>
  37. </p>
  38. </nav>
  39. </header>
  40. <section>
  41. <h1 property="schema:name">Le langage de template Django : Pour les auteurs de templates</h1>
  42. <article typeof="schema:BlogPosting">
  43. <div property="schema:articleBody">
  44. <img src="/static/david/biologeek/images/logos/django.png" alt="vignette" style="float:left; margin: 0.5em 1em;" property="schema:thumbnailUrl" />
  45. <p>Le langage de template Django a été conçu dans l'idée d'être un bon compromis
  46. entre puissance et facilité. Il est facilement accessible aux personnes ayant
  47. l'habitude de travailler avec du HTML. Si vous avez déjà utilisé un autre
  48. langage de template, comme <a class="reference" href="http://smarty.php.net/">Smarty</a> ou <a class="reference" href="http://www.cheetahtemplate.org/">CheetahTemplate</a>, vous n'aurez aucune
  49. difficulté à adopter les templates Django.</p>
  50. <div class="section">
  51. <h1><a id="templates" name="templates">Templates</a></h1>
  52. <p>Un template est un simple fichier texte. Il peut générer n'importe quel type de
  53. fichier texte (HTML, XML, CSV, etc).</p>
  54. <p>Un template contient des <strong>variables</strong> qui seront remplacées par leurs valeurs
  55. lors de son évaluation et des <strong>tags</strong> qui controlent la logique du template.</p>
  56. <p>Ci-dessous un template minimal qui illustre les bases. Chaque élément sera
  57. expliqué plus tard dans ce document.:</p>
  58. <pre class="literal-block">
  59. {% extends &quot;base_generic.html&quot; %}
  60. {% block title %}{{ section.title }}{% endblock %}
  61. {% block content %}
  62. &lt;h1&gt;{{ section.title }}&lt;/h1&gt;
  63. {% for story in story_list %}
  64. &lt;h2&gt;
  65. &lt;a href=&quot;{{ story.get_absolute_url }}&quot;&gt;
  66. {{ story.headline|upper }}
  67. &lt;/a&gt;
  68. &lt;/h2&gt;
  69. &lt;p&gt;{{ story.tease|truncatewords:&quot;100&quot; }}&lt;/p&gt;
  70. {% endfor %}
  71. {% endblock %}
  72. </pre>
  73. <div class="admonition-philosophie admonition">
  74. <p class="first admonition-title">Philosophie</p>
  75. <p>Pourquoi utiliser un template au format texte et non au format XML (comme
  76. celui du TAL Zope) ? Nous voulions que le langage de template puisse être
  77. utilisé pour plus que des templates XML/HTML. À World Online, nous
  78. l'utilisons pour les mails, la JavaScript et le CSV. Vous pouvez utiliser le
  79. langage de template pour tout format basé sur du texte.</p>
  80. <p class="last">Oh, encore un truc : Rendre du XML éditable par les humains est sadique !</p>
  81. </div>
  82. </div>
  83. <div class="section">
  84. <h1><a id="variables" name="variables">Variables</a></h1>
  85. <p>Les variables ressemblent à <tt class="docutils literal"><span class="pre">{{</span> <span class="pre">variable</span> <span class="pre">}}</span></tt>. Lorsque le moteur de template
  86. rencontre une variable, il évalue cette variable et la remplace par son
  87. résultat.</p>
  88. <p>Utilisez un point (<tt class="docutils literal"><span class="pre">.</span></tt>) pour accéder aux attributs d'une variable.</p>
  89. <div class="admonition-en-coulisses admonition">
  90. <p class="first admonition-title">En coulisses</p>
  91. <p>Techniquement, lorsque le système de template rencontre un point, il
  92. effectue les recherches suivantes, dans cet ordre :</p>
  93. <blockquote class="last">
  94. <ul class="simple">
  95. <li>Dictionaire</li>
  96. <li>Attribut</li>
  97. <li>Appel de méthode</li>
  98. <li>Index de liste</li>
  99. </ul>
  100. </blockquote>
  101. </div>
  102. <p>Dans le précédent exemple, <tt class="docutils literal"><span class="pre">{{</span> <span class="pre">section.title</span> <span class="pre">}}</span></tt> sera remplacé par l'attribut
  103. <tt class="docutils literal"><span class="pre">title</span></tt> de l'objet <tt class="docutils literal"><span class="pre">section</span></tt>.</p>
  104. <p>Si vous utilisez une variable qui n'existe pas, le système de template va
  105. insérer la valeur contenue dans le paramètre <tt class="docutils literal"><span class="pre">TEMPLATE_STRING_IF_INVALID</span></tt> qui
  106. correspond par défaut à <tt class="docutils literal"><span class="pre">''</span></tt> (chaîne vide).</p>
  107. <p>Lisez <a class="reference" href="#utiliser-les-r-f-rences-incluses">Utiliser les références incluses</a>, ci-dessous, pour vous aider à
  108. connaître les variables disponibles pour un template donné.</p>
  109. <p></div>
  110. <div class="section">
  111. <h1><a id="filtres" name="filtres">Filtres</a></h1>
  112. <p>Vous pouvez modifier des variables lors de l'affichage en utilisant des
  113. <strong>filtres</strong>.</p>
  114. <p>Les filtres ressemblent à <tt class="docutils literal"><span class="pre">{{</span> <span class="pre">name|lower</span> <span class="pre">}}</span></tt>. Ceci affiche la valeur de la
  115. variable <tt class="docutils literal"><span class="pre">{{</span> <span class="pre">name</span> <span class="pre">}}</span></tt> après avoir été filtrée par le filtre <tt class="docutils literal"><span class="pre">lower</span></tt>, qui
  116. convertit un texte en minuscule. Utilisez un pipe (<tt class="docutils literal"><span class="pre">|</span></tt>) pour appliquer un
  117. filtre.</p></p>
  118. <p>Les filtres peuvent « s'enchaîner ». La sortie d'un filtre est l'entrée du
  119. suivant. <tt class="docutils literal"><span class="pre">{{</span> <span class="pre">text|escape|linebreaks</span> <span class="pre">}}</span></tt> est souvent utilisé pour échapper le
  120. contenu d'un texte et convertir ensuite les sauts de lignes en tags <tt class="docutils literal"><span class="pre">&lt;p&gt;</span></tt>.</p>
  121. <p>Certains filtres possèdent des arguments. Un argument de filtre ressemble à :
  122. <tt class="docutils literal"><span class="pre">{{</span> <span class="pre">bio|truncatewords:&quot;30&quot;</span> <span class="pre">}}</span></tt>. Cela va afficher les 30 premiers mots de la
  123. variable <tt class="docutils literal"><span class="pre">bio</span></tt>. Les arguments de filtres sont toujours entre double quotes.</p>
  124. <p>La <a class="reference" href="#r-f-rence-des-filtres-inclus">Référence des filtres inclus</a> ci-dessous décrit l'ensemble des ces filtres.</p>
  125. <p></div>
  126. <div class="section">
  127. <h1><a id="tags" name="tags">Tags</a></h1>
  128. <p>Les tags ressemblent à : <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">tag</span> <span class="pre">%}</span></tt>. Les tags sont plus compliqués que les
  129. variables : certains génèrent une sortie de texte, d'autres contrôlent le flux
  130. grâce aux boucles ou à la logique, et certains chargent des informations
  131. externes dans le template pouvant être utilisées par la suite.</p></p>
  132. <p>Certains tags requièrent des tags de début et de fin (càd.
  133. <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">tag</span> <span class="pre">%}</span> <span class="pre">...</span> <span class="pre">contenu</span> <span class="pre">du</span> <span class="pre">tag</span> <span class="pre">...</span> <span class="pre">{%</span> <span class="pre">endtag</span> <span class="pre">%}</span></tt>). La
  134. <a class="reference" href="#r-f-rence-des-tags-inclus">Référence des tags inclus</a> ci-dessous décris l'ensemble de ces tags. Vous
  135. pouvez écrire vos propres tags si vous connaissez le Python.</p>
  136. <p></div>
  137. <div class="section">
  138. <h1><a id="h-ritage-des-templates" name="h-ritage-des-templates">Héritage des templates</a></h1>
  139. <p>La plus intéressante -- mais aussi la plus complexe -- partie du moteur de
  140. template de Django est l'héritage. L'héritage des templates vous permet de
  141. construire un template « squelette » de base contenant tous les éléments usuels
  142. de votre site et définissant des blocs que les templates enfants pourront
  143. écraser et/ou compléter.</p>
  144. <p>Il est plus simple, pour comprendre l'héritage des templates, de commencer par
  145. un exemple:</p>
  146. <pre class="literal-block">
  147. &lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;
  148. &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</p>
  149. <p>&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;
  150. &lt;head&gt;
  151. &lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot; /&gt;</p>
  152. <pre><code>&amp;lt;title&amp;gt;{% block title %}Mon super site{% endblock %}&amp;lt;/title&amp;gt;
  153. </code></pre>
  154. <p>&lt;/head&gt;</p>
  155. <p>&lt;body&gt;
  156. &lt;div id=&quot;sidebar&quot;&gt;
  157. {% block sidebar %}
  158. &lt;ul&gt;</p>
  159. <pre><code> &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/&amp;quot;&amp;gt;Accueil&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
  160. &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/blog/&amp;quot;&amp;gt;Blog&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
  161. &amp;lt;/ul&amp;gt;
  162. {% endblock %}
  163. &amp;lt;/div&amp;gt;
  164. &amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;
  165. {% block content %}{% endblock %}
  166. &amp;lt;/div&amp;gt;
  167. </code></pre>
  168. <p>&lt;/body&gt;
  169. </pre>
  170. <p>Ce template, que nous appelerons <tt class="docutils literal"><span class="pre">base.html</span></tt>, définit un simple squelette HTML
  171. que vous pouvez utiliser pour une page à deux colonnes. C'est le boulot des
  172. templates « enfants » de compléter les blocs vides avec du contenu.</p></p>
  173. <p>Dans cet exemple, le tag <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">%}</span></tt> définit trois blocs que les templates
  174. enfants peuvent compléter. Tout ce que les tags <tt class="docutils literal"><span class="pre">block</span></tt> font c'est d'indiquer
  175. au moteur de template qu'un template enfant peut écraser ces parties du
  176. template.</p>
  177. <p>Un template enfant pourrait ressembler à ça:</p>
  178. <pre class="literal-block">
  179. {% extends &quot;base.html&quot; %}
  180. {% block title %}Mon super blog{% endblock %}
  181. {% block content %}
  182. {% for entry in blog_entries %}
  183. &lt;h2&gt;{{ entry.title }}&lt;/h2&gt;
  184. &lt;p&gt;{{ entry.body }}&lt;/p&gt;
  185. {% endfor %}
  186. {% endblock %}
  187. </pre>
  188. <p>Le tag <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">extends</span> <span class="pre">%}</span></tt> est la clé ici. Il indique au moteur de template que ce
  189. template « étend » un autre template. Lorsque le système de template évalue ce
  190. template, il commence par localiser le parent -- dans notre cas, « base.html ».</p>
  191. <p>À ce moment, le moteur de template va tenir compte des trois tags
  192. <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">%}</span></tt> dans <tt class="docutils literal"><span class="pre">base.html</span></tt> et remplacer ces blocs avec le contenu du
  193. template enfant. En fonction de la valeur de <tt class="docutils literal"><span class="pre">blog_entries</span></tt>, la sortie devrait
  194. être proche de:</p>
  195. <pre class="literal-block">
  196. &lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;
  197. &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
  198. &lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;
  199. &lt;head&gt;
  200. &lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot; /&gt;
  201. &lt;title&gt;Mon super blog&lt;/title&gt;
  202. &lt;/head&gt;
  203. &lt;body&gt;
  204. &lt;div id=&quot;sidebar&quot;&gt;
  205. &lt;ul&gt;
  206. &lt;li&gt;&lt;a href=&quot;/&quot;&gt;Accueil&lt;/a&gt;&lt;/li&gt;
  207. &lt;li&gt;&lt;a href=&quot;/blog/&quot;&gt;Blog&lt;/a&gt;&lt;/li&gt;
  208. &lt;/ul&gt;
  209. &lt;/div&gt;
  210. &lt;div id=&quot;content&quot;&gt;
  211. &lt;h2&gt;Billet un&lt;/h2&gt;
  212. &lt;p&gt;C'est mon premier billet.&lt;/p&gt;
  213. &lt;h2&gt;Billet deux&lt;/h2&gt;
  214. &lt;p&gt;C'est mon second billet.&lt;/p&gt;
  215. &lt;/div&gt;
  216. &lt;/body&gt;
  217. </pre>
  218. <p>Notez que tant que le template enfant ne redéfinit pas le bloc <tt class="docutils literal"><span class="pre">sidebar</span></tt>, la
  219. valeur du template parent est utilisée à la place. Le contenu au sein d'un tag
  220. <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">%}</span></tt> dans un template parent est toujours utilisé en dernier lieu.</p>
  221. <p>Vous pouvez utiliser autant de niveaux d'héritage que désiré. L'une des manières
  222. habituelle d'utiliser l'héritage est l'approche à trois niveaux suivante :</p>
  223. <blockquote>
  224. <ul class="simple">
  225. <li>Créez un template <tt class="docutils literal"><span class="pre">base.html</span></tt> qui définit l'apparence globale de votre
  226. site.</li>
  227. <li>Créez un template <tt class="docutils literal"><span class="pre">base_NOMDESECTION.html</span></tt> pour chaque section de votre
  228. site. Par exemple, <tt class="docutils literal"><span class="pre">base_news.html</span></tt>, <tt class="docutils literal"><span class="pre">base_sports.html</span></tt>. Ces templates
  229. étendent tous <tt class="docutils literal"><span class="pre">base.html</span></tt> et incluent le style/design spécifique à la
  230. section.</li>
  231. <li>Créez un template individuel pour chaque type de page, comme les articles
  232. de nouveautés ou les billets d'un blog. Ces templates étendent le template
  233. de la section appropriée.</li>
  234. </ul>
  235. </blockquote>
  236. <p>Cette approche maximise la réutilisation du code et rend facile l'ajout de blocs
  237. partagés entre plusieurs parties du site comme la navigation.</p>
  238. <p>Voici quelques astuces pour utiliser l'héritage :</p>
  239. <blockquote>
  240. <ul class="simple">
  241. <li>Si vous utilisez <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">extends</span> <span class="pre">%}</span></tt> dans un template, ça doit être le
  242. premier tag du template. Dans le cas contraire l'héritage ne fonctionnera
  243. pas.</li>
  244. <li>Il vaut mieux avoir de nombreux tags <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">%}</span></tt> dans vos templates de
  245. base. Rappelez-vous, les templates enfants n'ont pas à redéfinir la
  246. totalité des blocs, vous pouvez donc remplir les blocs avec un contenu
  247. intéressant par défaut. Ne redéfinissez ensuite que ceux dont vous avez
  248. besoin. Il vaut mieux en avoir plus que pas assez.</li>
  249. <li>Si vous vous apercevez d'une duplication du contenu dans de nombreux
  250. templates, cela signifie probablement que vous devriez déplacer ce contenu
  251. dans un <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">%}</span></tt> au sein d'un template parent.</li>
  252. <li>Si vous avez besoin du contenu issu du template parent, la variable
  253. <tt class="docutils literal"><span class="pre">{{</span> <span class="pre">block.super</span> <span class="pre">}}</span></tt> est là pour ça. C'est intéressant si vous souhaitez
  254. ajouter quelquechose au contenu parent existant au lieu de l'écraser.</li>
  255. </ul>
  256. </blockquote>
  257. <p>Pour finir, notez l'impossibilité de définir plusieurs tags <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">block</span> <span class="pre">%}</span></tt>
  258. ayant le même nom dans le même template. Cette limitation existe car un tag
  259. block fonctionne dans les deux directions. Cela signifie qu'un tag block ne
  260. procure pas seulement un espace à compléter -- il définit aussi au niveau enfant
  261. le contenu parent accessible dans cet espace (par <tt class="docutils literal"><span class="pre">block.super</span></tt>).</p>
  262. <p></div>
  263. <div class="section">
  264. <h1><a id="utiliser-les-r-f-rences-incluses" name="utiliser-les-r-f-rences-incluses">Utiliser les références incluses</a></h1></p>
  265. <p>L'interface d'administration de Django inclue une référence complète à
  266. l'ensemble des tags et filtres de template disponibles pour un site donné. Pour
  267. y accéder, rendez vous dans votre interface d'administration et cliquez sur le
  268. lien « Documentation » en haut à droite de la page.</p>
  269. <p>La référence est divisée en 4 sections : tags, filtres, modèles et vues.</p>
  270. <p>Les sections <strong>tags</strong> et <strong>filtres</strong> décrivent tous les tags de base (en fait,
  271. les références de tag et de filtre qui suivent proviennent directement de ces
  272. pages) ainsi que vos propres bibliothèques de tags et de filtres disponibles.</p>
  273. <p>La page des <strong>vues</strong> est la plus intéressante. Chaque URL de votre site a une
  274. entrée distincte ici, et cliquer sur cette URL vous donnera accès :</p>
  275. <blockquote>
  276. <ul class="simple">
  277. <li>Au nom de la fonction qui génère cette vue.</li>
  278. <li>À une description succinte de ce que fait la vue.</li>
  279. <li>Au <strong>contexte</strong>, ou une liste de variables accessibles dans le template de
  280. la vue.</li>
  281. <li>Au nom du ou des template(s) qui est(sont) utilisé(s) pour cette vue.</li>
  282. </ul>
  283. </blockquote>
  284. <p>Chaque page de documentation d'une vue dispose aussi d'un bookmarklet que vous
  285. pouvez utiliser pour aller directement de n'importe quelle page à la page de
  286. documentation de cette vue.</p>
  287. <p>Les sites propulsés par Django utilisant généralement des objets de base de
  288. données, la section <strong>modèles</strong> de la page de documentation décrit chaque type
  289. d'objet dans le système courant avec l'ensemble des champs disponibles dans cet
  290. objet.</p>
  291. <p>L'ensemble des pages de documentation vous renseigne sur chaque tag, filtre,
  292. variable et objet disponible pour un template donné.</p>
  293. <p></div>
  294. <div class="section">
  295. <h1><a id="tags-personnalis-s-et-bilbioth-ques-de-filtres" name="tags-personnalis-s-et-bilbioth-ques-de-filtres">Tags personnalisés et bilbiothèques de filtres</a></h1>
  296. <p>Certaines applications procurent des tags personnalisés et des bilbiothèques de
  297. filtres. Pour y accéder dans un template, utilisez le tag <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">load</span> <span class="pre">%}</span></tt>:</p>
  298. <pre class="literal-block">
  299. {% load comments %}</p>
  300. <p>{% comment_form for blogs.entries entry.id with is_public yes %}
  301. </pre></p>
  302. <p>Ci-dessus, le tag <tt class="docutils literal"><span class="pre">load</span></tt> charge la bibliothèque de tags <tt class="docutils literal"><span class="pre">comments</span></tt>, ce qui
  303. rend ensuite le tag <tt class="docutils literal"><span class="pre">comment_form</span></tt> utilisable. Consultez la rubrique
  304. documentation de votre interface d'administration pour trouver la liste des
  305. bibliothèques personnalisées de votre installation.</p>
  306. <p>Le tag <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">load</span> <span class="pre">%}</span></tt> peut prendre plusieurs noms de bibliothèques à la fois,
  307. séparés par des espaces. Exemple:</p>
  308. <pre class="literal-block">
  309. {% load comments i18n %}
  310. </pre>
  311. <div class="section">
  312. <h2><a id="biblioth-ques-personnalis-es-et-h-ritage-des-templates" name="biblioth-ques-personnalis-es-et-h-ritage-des-templates">Bibliothèques personnalisées et héritage des templates</a></h2>
  313. <p>Lorsque vous chargez un tag personnalisé ou une bibliothèque de filtres, les
  314. tags/filtres ne sont accessibles qu'au sein du template courant -- et aucun des
  315. templates parents ou enfants issus de l'héritage des templates n'y a accès.</p>
  316. <p>Par exemple, si un template <tt class="docutils literal"><span class="pre">foo.html</span></tt> a <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">load</span> <span class="pre">comments</span> <span class="pre">%}</span></tt>, un template
  317. enfant (par exemple, un qui a <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">extends</span> <span class="pre">&quot;foo.html&quot;</span> <span class="pre">%}</span></tt>) n'aura <em>pas</em> accès
  318. aux filtres et tags du template comments. Le template enfant doit avoir son
  319. propre <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">load</span> <span class="pre">comments</span> <span class="pre">%}</span></tt>.</p>
  320. <p>C'est une fonctionnalité pour la maintenabilité et l'intégrité des templates.</p>
  321. </div>
  322. <p></div>
  323. <div class="section">
  324. <h1><a id="r-f-rence-des-tags-et-filtres-inclus" name="r-f-rence-des-tags-et-filtres-inclus">Référence des tags et filtres inclus</a></h1>
  325. <p>Pour ceux ne disposant pas d'une interface d'administration, la référence des
  326. tags et filtres suit. En raison de la personnalisation possible de Django, la
  327. référence dans votre administration prévaut sur celle-ci concernant
  328. l'accessibilité et la fonction des tags et filtres.</p>
  329. <div class="section">
  330. <h2><a id="r-f-rence-des-tags-inclus" name="r-f-rence-des-tags-inclus">Référence des tags inclus</a></h2>
  331. </div>
  332. <div class="section">
  333. <h2><a id="r-f-rence-des-filtres-inclus" name="r-f-rence-des-filtres-inclus">Référence des filtres inclus</a></h2>
  334. <p><strong>La suite de la traduction est en cours</strong>, j'ai jugé qu'il était plus important
  335. de publier cette première partie qui pose les bases en attendant. Il faut avouer
  336. que <a class="reference" href="http://www.djangoproject.com/documentation/templates/#built-in-tag-and-filter-reference">la suite (en)</a> est moins passionnante...</p></p>
  337. <p>Vous pouvez maintenant retourner à la <a class="reference" href="https://larlet.fr/david/biologeek/archives/20060617-traduction-francaise-de-la-documentation-de-django-le-framework-web-python/">page d'accueil des traductions de la
  338. documentation de Django</a>.</p>
  339. <p>Cette traduction correspond à la révision 3589 (post 0.95).</p>
  340. <p></div>
  341. </div></p>
  342. </div>
  343. </article>
  344. <footer>
  345. <h6 property="schema:datePublished">— 15/08/2006</h6>
  346. </footer>
  347. </section>
  348. <section>
  349. <div>
  350. <h3>Articles peut-être en rapport</h3>
  351. <ul>
  352. <li><a href="/david/biologeek/archives/20060715-comparaison-de-turbogears-et-django-deux-frameworks-web-python/" title="Accès à Comparaison de TurboGears et Django, deux frameworks web Python">Comparaison de TurboGears et Django, deux frameworks web Python</a></li>
  353. <li><a href="/david/biologeek/archives/20060617-redaction-de-votre-premiere-appli-django-partie-4-conception-d-un-formulaire-et-vues-generiques/" title="Accès à Rédaction de votre première appli Django, partie 4 : Conception d&#39;un formulaire et vues génériques">Rédaction de votre première appli Django, partie 4 : Conception d&#39;un formulaire et vues génériques</a></li>
  354. <li><a href="/david/biologeek/archives/20060617-redaction-de-votre-premiere-appli-django-partie-3-creation-des-vues-de-l-interface-publique/" title="Accès à Rédaction de votre première appli Django, partie 3 : Création des vues de l&#39;interface publique">Rédaction de votre première appli Django, partie 3 : Création des vues de l&#39;interface publique</a></li>
  355. </ul>
  356. </div>
  357. </section>
  358. <section>
  359. <div id="comments">
  360. <h3>Commentaires</h3>
  361. <div class="comment" typeof="schema:UserComments">
  362. <p class="comment-meta">
  363. <span class="comment-author" property="schema:creator">Bernard</span> le <span class="comment-date" property="schema:commentTime">16/08/2006</span> :
  364. </p>
  365. <div class="comment-content" property="schema:commentText">
  366. <p>waaaoou merci beaucoup! J'en suis a mes premiers babultiements en Python et je voulais justement utiliser django pour un projet web personnel!</p>
  367. </div>
  368. </div>
  369. <div class="comment" typeof="schema:UserComments">
  370. <p class="comment-meta">
  371. <span class="comment-author" property="schema:creator">djangofan</span> le <span class="comment-date" property="schema:commentTime">13/11/2006</span> :
  372. </p>
  373. <div class="comment-content" property="schema:commentText">
  374. <p><a href="http://www.djangobook.com/en/beta/" title="http://www.djangobook.com/en/beta/" rel="nofollow">www.djangobook.com/en/bet...</a><br />
  375. <br />
  376. -&gt; <a href="http://www.djangobook.com/fr/beta/" title="http://www.djangobook.com/fr/beta/" rel="nofollow">www.djangobook.com/fr/bet...</a><br />
  377. <br />
  378. :D a mission for biologeek !</p>
  379. </div>
  380. </div>
  381. <div class="comment" typeof="schema:UserComments">
  382. <p class="comment-meta">
  383. <span class="comment-author" property="schema:creator">djangofan</span> le <span class="comment-date" property="schema:commentTime">13/11/2006</span> :
  384. </p>
  385. <div class="comment-content" property="schema:commentText">
  386. <p>Une petite question à propos des templates. J'ai une classe Annonce à laquelle se rattache une classe Photo. Je voudrais afficher une photo dans ma page web, mais je n'arrive pas à extraire l'url du lien.<br />
  387. <br />
  388. J'ai essayé :<br />
  389. <br />
  390. &lt;img src=&quot;{{ annonce.photo[1].url }}&quot; width=&quot;120&quot; height=&quot;90&quot; /&gt;<br />
  391. &lt;img src=&quot;{{ annonce.photo(1).url }}&quot; width=&quot;120&quot; height=&quot;90&quot; /&gt;<br />
  392. <br />
  393. mais ça fonctionne pas. Une idée de la syntaxe à utiliser ?<br />
  394. <br />
  395. Merci<br />
  396. </p>
  397. </div>
  398. </div>
  399. <div class="comment" typeof="schema:UserComments">
  400. <p class="comment-meta">
  401. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">13/11/2006</span> :
  402. </p>
  403. <div class="comment-content" property="schema:commentText">
  404. <p>Normalement, tu dois avoir créé une méthode get_aboslute_url() dans ton model qui te permet de récupérer cette url, cf la doc :<br />
  405. <br />
  406. <a href="http://www.djangoproject.com/documentation/model_api/#get-absolute-url" title="http://www.djangoproject.com/documentation/model_api/#get-absolute-url" rel="nofollow">www.djangoproject.com/doc...</a>
  407. <br /><br />
  408. ps : et pour le djangobook c'est en cours de réflexion ;-).
  409. </p>
  410. </div>
  411. </div>
  412. <div class="comment" typeof="schema:UserComments">
  413. <p class="comment-meta">
  414. <span class="comment-author" property="schema:creator">djangofan</span> le <span class="comment-date" property="schema:commentTime">13/11/2006</span> :
  415. </p>
  416. <div class="comment-content" property="schema:commentText">
  417. <p>En fait c'est pas ça, d'ailleurs quand je me relis, c'est pas clair. :-D<br />
  418. Ce que je voudrais en faite c'est acceder à la valeur de la propriété url de la classe photo. Elle meme est une &quot;sous-classe&quot; de la classe annonce.<br />
  419. <br />
  420. Je sais pas si je suis bien compréhensible !<br />
  421. <br />
  422. </p>
  423. </div>
  424. </div>
  425. <div class="comment" typeof="schema:UserComments">
  426. <p class="comment-meta">
  427. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">13/11/2006</span> :
  428. </p>
  429. <div class="comment-content" property="schema:commentText">
  430. <p>Pas vraiment :D<br />
  431. Il y a un moyen que tu me colles ton model quelquepart (ou par mail ?)</p>
  432. </div>
  433. </div>
  434. <div class="comment" typeof="schema:UserComments">
  435. <p class="comment-meta">
  436. <span class="comment-author" property="schema:creator">DjangoJO</span> le <span class="comment-date" property="schema:commentTime">21/12/2006</span> :
  437. </p>
  438. <div class="comment-content" property="schema:commentText">
  439. <p>Bonjour,<br />
  440. <br />
  441. Voilà une petite question qui se pose !<br />
  442. J'ai un projet principale qui comporte une partie blog et une partie sondage et accueil. Comment faire pour appeler mon template accueil en y incorporant mon blog et mon sondage?<br />
  443. <br />
  444. personnellement j'y arrive en appellant sondage herité de accueil OU blog herité de accueil mais je n'arrive pas à avoir les deux dans mon template accueil.<br />
  445. <br />
  446. Merci </p>
  447. </div>
  448. </div>
  449. <div class="comment" typeof="schema:UserComments">
  450. <p class="comment-meta">
  451. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">21/12/2006</span> :
  452. </p>
  453. <div class="comment-content" property="schema:commentText">
  454. <p>Il y a trois solutions :<br />
  455. <br />
  456. * soit tu passes par les vues génériques et dans ce cas il faut lire l'article de James <a href="http://www.b-list.org/weblog/2006/11/16/django-tips-get-most-out-generic-views" title="http://www.b-list.org/weblog/2006/11/16/django-tips-get-most-out-generic-views" rel="nofollow">www.b-list.org/weblog/200...</a><br />
  457. <br />
  458. * soit tu mets tout ce dont tu as besoin dans le dictionnaire permettant que tu passes à ta vue.<br />
  459. <br />
  460. * soit tu utilises les templatetags, une explication sur b-list aussi (site de référence) : <a href="http://www.b-list.org/weblog/2006/06/07/django-tips-write-better-template-tags" title="http://www.b-list.org/weblog/2006/06/07/django-tips-write-better-template-tags" rel="nofollow">www.b-list.org/weblog/200...</a>.<br />
  461. <br />
  462. Tu peux m'envoyer ton code si tu veux plus d'explications.<br />
  463. </p>
  464. </div>
  465. </div>
  466. <div class="comment" typeof="schema:UserComments">
  467. <p class="comment-meta">
  468. <span class="comment-author" property="schema:creator">djangofan2</span> le <span class="comment-date" property="schema:commentTime">21/02/2007</span> :
  469. </p>
  470. <div class="comment-content" property="schema:commentText">
  471. <p>J'ai un champs :<br />
  472. CV = models.FileField(&quot;CV &quot;, upload_to=&quot;candidats/&quot;, blank=True)<br />
  473. <br />
  474. Et dans mon template je fait : <br />
  475. <br />
  476. &lt;input type=&quot;file&quot; size=55 maxlength=100000 name=&quot;CV&quot; id=&quot;id_CV&quot;&gt;<br />
  477. <br />
  478. Puis je vérifie dans ma partie administration et dans le champs CV il met que le nom du fichier donc il ne me telecharge pas dans le dossier&quot;candidats&quot; le CV!!!<br />
  479. (( ce qui marche bien sur si je rajoute une candidature à la main dans la partie administration.<br />
  480. <br />
  481. Quelqu'un pourrai m'aider SVP.<br />
  482. <br />
  483. Merci<br />
  484. <br />
  485. <br />
  486. </p>
  487. </div>
  488. </div>
  489. <div class="comment" typeof="schema:UserComments">
  490. <p class="comment-meta">
  491. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">21/02/2007</span> :
  492. </p>
  493. <div class="comment-content" property="schema:commentText">
  494. <p>@djangofan2 : tu peux essayer de mettre un chemin absolu pour l'upload. Ah et n'oublie pas les " pour les valeurs de tes attributs dans ton html (pour size et maxlength).</p>
  495. </div>
  496. </div>
  497. <div class="comment" typeof="schema:UserComments">
  498. <p class="comment-meta">
  499. <span class="comment-author" property="schema:creator">DjangoFan2</span> le <span class="comment-date" property="schema:commentTime">26/02/2007</span> :
  500. </p>
  501. <div class="comment-content" property="schema:commentText">
  502. <p>Bonjour,<br />
  503. <br />
  504. J'aimerai tout simplement savoir si il est possible d'utiliser le search_field de la partie admin de django dans un template personnel ?<br />
  505. <br />
  506. A part si bien sûr, il existe un module de recherche de django ? ou bien alors il faut le faire soit même ?<br />
  507. <br />
  508. Comme on peut le voir sur la plus part des sites internet il y a toujours une zone recherche ...<br />
  509. <br />
  510. Merci</p>
  511. </div>
  512. </div>
  513. <div class="comment" typeof="schema:UserComments">
  514. <p class="comment-meta">
  515. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">26/02/2007</span> :
  516. </p>
  517. <div class="comment-content" property="schema:commentText">
  518. <p>@DjangoFan2 : c'est une vue à coder soit-même car elle est très spécifique de l'application développée.</p>
  519. </div>
  520. </div>
  521. <div class="comment" typeof="schema:UserComments">
  522. <p class="comment-meta">
  523. <span class="comment-author" property="schema:creator">DjangoFan2</span> le <span class="comment-date" property="schema:commentTime">26/02/2007</span> :
  524. </p>
  525. <div class="comment-content" property="schema:commentText">
  526. <p>Merci,<br />
  527. Bien je vais m'y mettre sans trop tarder alors !!!<br />
  528. <br />
  529. Et juste pour savoir :: <br />
  530. - j'ai un menu en javascript qui fonctionne très bien mais quand j'utilise les fichiers js de django genre calendar.js il ne se passe rien serais-tu pourquoi ?<br />
  531. <br />
  532. - L'utilisation d'ajax est-il possible ? si oui comment faire pour inclure un fichier (exemple en php :&lt;? include(&quot;menu.php&quot;);?&gt;<br />
  533. <br />
  534. Merci beaucoup pour tous ses renseignements !!!<br />
  535. <br />
  536. <br />
  537. </p>
  538. </div>
  539. </div>
  540. <div class="comment" typeof="schema:UserComments">
  541. <p class="comment-meta">
  542. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">26/02/2007</span> :
  543. </p>
  544. <div class="comment-content" property="schema:commentText">
  545. <p>&gt; j'ai un menu en javascript qui fonctionne très bien mais quand j'utilise les fichiers js de django genre calendar.js il ne se passe rien serais-tu pourquoi ?<br />
  546. <br />
  547. Il doit y avoir un conflit entre les variables js de tes deux fichiers (?)<br />
  548. <br />
  549. &gt; L'utilisation d'ajax est-il possible ? <br />
  550. <br />
  551. Bien sûr !<br />
  552. <br />
  553. &gt; si oui comment faire pour inclure un fichier (exemple en php :&lt;? include(&quot;menu.php&quot;);?&gt;<br />
  554. <br />
  555. Ça c'est de l'héritage de template, pas de l'AJAX. cf le billet de Jeff Croft : <a href="http://www2.jeffcroft.com/blog/2006/feb/25/django-templates-the-power-of-inheritance/" title="http://www2.jeffcroft.com/blog/2006/feb/25/django-templates-the-power-of-inheritance/" rel="nofollow">www2.jeffcroft.com/blog/2...</a><br />
  556. </p>
  557. </div>
  558. </div>
  559. <div class="comment" typeof="schema:UserComments">
  560. <p class="comment-meta">
  561. <span class="comment-author" property="schema:creator">djangoNew</span> le <span class="comment-date" property="schema:commentTime">28/02/2007</span> :
  562. </p>
  563. <div class="comment-content" property="schema:commentText">
  564. <p>Merci beaucoup pour le tuto, c'est très clair et bien expliqué .<br />
  565. <br />
  566. Par contre j'aimerai savoir si c'est possible de comparer une variable dans les &quot;if&quot; ( exemple : {% if cpt=2 %} ou faire le même style d'opération comme en php.<br />
  567. <br />
  568. Car j'ai créer un menu en html et javascript, mais j'ai besoin que ce menu soit complétement dynamique donc il faut que je le remplisse via un modéle.<br />
  569. <br />
  570. Merci beaucoup<br />
  571. <br />
  572. Et encore bravo pour le site</p>
  573. </div>
  574. </div>
  575. <div class="comment" typeof="schema:UserComments">
  576. <p class="comment-meta">
  577. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">28/02/2007</span> :
  578. </p>
  579. <div class="comment-content" property="schema:commentText">
  580. <p>Il existe ifequal pour ça : {% ifequal cpt 2 %}<br />
  581. <br />
  582. Mais pour ton cas, un block extraclass dans chacune des classes de ton menu devrait être plus adapté, enfin c'est ainsi que je procède...<br />
  583. <br />
  584. Bienvenue dans l'univers Django :-)</p>
  585. </div>
  586. </div>
  587. <div class="comment" typeof="schema:UserComments">
  588. <p class="comment-meta">
  589. <span class="comment-author" property="schema:creator">djangoNew</span> le <span class="comment-date" property="schema:commentTime">02/03/2007</span> :
  590. </p>
  591. <div class="comment-content" property="schema:commentText">
  592. <p>Me revoilà pour d'autre petites questions sur des choses que je n'ai pas trop trop compris !<br />
  593. Merci encore pour toutes ses explications !<br />
  594. <br />
  595. C'est une question d'heritage ! En ayant deux module différents genre contact et FAQ comment puis je heriter leurs templates respectif sur un même template general genre base.html !!!<br />
  596. <br />
  597. J'ai compris l'histoire des templates car c'est très bien expliqué mais là je suis un peu perdu !<br />
  598. <br />
  599. MERCI d'avance<br />
  600. </p>
  601. </div>
  602. </div>
  603. <div class="comment" typeof="schema:UserComments">
  604. <p class="comment-meta">
  605. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">03/03/2007</span> :
  606. </p>
  607. <div class="comment-content" property="schema:commentText">
  608. <p>Il suffit de faire un {% extends &quot;base.html&quot; %} en première ligne de ton template. Si tu veux tu peux regarder ce que ça donne pour le site de django-fr.org : <a href="http://trac.django-fr.org/trac/browser/site/trunk" title="http://trac.django-fr.org/trac/browser/site/trunk" rel="nofollow">trac.django-fr.org/trac/b...</a></p>
  609. </div>
  610. </div>
  611. <div class="comment" typeof="schema:UserComments">
  612. <p class="comment-meta">
  613. <span class="comment-author" property="schema:creator">djangoNew</span> le <span class="comment-date" property="schema:commentTime">05/03/2007</span> :
  614. </p>
  615. <div class="comment-content" property="schema:commentText">
  616. <p>Merci pour le lien, j'ai regardé les différents templates mais le probléme qui se pour moi, ne se pose pas pour les templates du lien en question, car le texte est rentré en dur dans la page, que personellement je recupére le texte d'une view.<br />
  617. <br />
  618. Je me suis peut être mal exprimé la derniére fois !<br />
  619. <br />
  620. La seule action qui déclenche une view c'est l'url en question (a ce que j'ai compris).<br />
  621. Si je veux afficher les articles de mon module et les contacts de mon autre module normalement il faut que j'appele la view &quot;Articles&quot; et la view &quot;Contact&quot; avec leurs url respectif ( genre : www.monsite/article et www.monsite/contact) !<br />
  622. Mais moi je voudrai que quand je tape par exemple l'url : www.monsite.com/accueil je puisse avoir les articles et les contacts en bas de la page base.html. <br />
  623. <br />
  624. Mais le problème qui se pose : Si j'appele www.monsite/Article, il vas me retourner la view correspondante avec la page article.html que j'&quot;extends&quot; de base.html mais comment faire pour que je puisse aussi appelé la view de contact et l'extends de base.html ??<br />
  625. <br />
  626. Désolé mais je ne n'arrive vraiment pas à voir comment je puisse faire et à cause de se probléme, je ne peux avancer sur mon projet personel ... <br />
  627. <br />
  628. <br />
  629. <br />
  630. </p>
  631. </div>
  632. </div>
  633. <div class="comment" typeof="schema:UserComments">
  634. <p class="comment-meta">
  635. <span class="comment-author" property="schema:creator">David, biologeek</span> le <span class="comment-date" property="schema:commentTime">05/03/2007</span> :
  636. </p>
  637. <div class="comment-content" property="schema:commentText">
  638. <p>Les solutions possibles dans ce cas sont répertoriées dans un précédent commentaire : le numéro 8 (un peu plus haut), notamment les templatetags qui sont je pense la solution la plus élégante.</p>
  639. </div>
  640. </div>
  641. <div class="comment" typeof="schema:UserComments">
  642. <p class="comment-meta">
  643. <span class="comment-author" property="schema:creator">Ouarnier</span> le <span class="comment-date" property="schema:commentTime">19/01/2010</span> :
  644. </p>
  645. <div class="comment-content" property="schema:commentText">
  646. <p>Bonjour,</p>
  647. <p>J&#39;ai un projet qui a deux applications. <br />dans chacune de ces applications, j&#39;ai une template defini. Une template qui affiche un budget de fonctionnement et dans l&#39;autre appli, une template qui affiche un budget de personnel.</p>
  648. <p>je voudrais faire une page tableau de bord qui affiche les deux templates ?<br />comment faire ?</p>
  649. <p>j&#39;ai lu le commentaire 8 mais je ne comprends pas comment faire ?<br />je n&#39;arrive pas à comprendre comment je peux faire ça avec les templates tags.</p>
  650. </div>
  651. </div>
  652. </div>
  653. </section>
  654. <footer>
  655. <nav>
  656. <p>
  657. <small>
  658. Je réponds quasiment toujours aux <a href="m&#x61;ilto:d&#x61;vid%40l&#x61;rlet&#46;fr" title="Envoyer un email">emails</a> (<a href="/david/signature/" title="Ma signature actuelle avec possibilité de chiffrement">signés</a>) et vous pouvez me rencontrer à Montréal. <span class="more-infos">N’hésitez pas à <a href="/david/log/" title="Être tenu informé des mises à jour">vous abonner</a> pour être tenu informé des publications récentes.</span>
  659. </small>
  660. </p>
  661. </nav>
  662. </footer>
  663. </div>
  664. <script src="/static/david/js/larlet-david-3ee43f.js" data-no-instant></script>
  665. <script data-no-instant>InstantClick.init()</script>
  666. </body>
  667. </html>