title:      Le langage de template Django : Pour les auteurs de templates
slug:       le-langage-de-template-django-pour-les-auteurs-de-templates
date:       2006-08-15 18:46:48
type:       post
vignette:   images/logos/django.png
contextual_title1:  Comparaison de TurboGears et Django, deux frameworks web Python
contextual_url1:    20060715-comparaison-de-turbogears-et-django-deux-frameworks-web-python
contextual_title2:  Rédaction de votre première appli Django, partie 4 : Conception d&#39;un formulaire et vues génériques
contextual_url2:    20060617-redaction-de-votre-premiere-appli-django-partie-4-conception-d-un-formulaire-et-vues-generiques
contextual_title3:  Rédaction de votre première appli Django, partie 3 : Création des vues de l&#39;interface publique
contextual_url3:    20060617-redaction-de-votre-premiere-appli-django-partie-3-creation-des-vues-de-l-interface-publique

<p>Le langage de template Django a été conçu dans l'idée d'être un bon compromis
entre puissance et facilité. Il est facilement accessible aux personnes ayant
l'habitude de travailler avec du HTML. Si vous avez déjà utilisé un autre
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
difficulté à adopter les templates Django.</p>

<div class="section">
<h1><a id="templates" name="templates">Templates</a></h1>
<p>Un template est un simple fichier texte. Il peut générer n'importe quel type de
fichier texte (HTML, XML, CSV, etc).</p>
<p>Un template contient des <strong>variables</strong> qui seront remplacées par leurs valeurs
lors de son évaluation et des <strong>tags</strong> qui controlent la logique du template.</p>
<p>Ci-dessous un template minimal qui illustre les bases. Chaque élément sera
expliqué plus tard dans ce document.:</p>
<pre class="literal-block">
{% extends &quot;base_generic.html&quot; %}

{% block title %}{{ section.title }}{% endblock %}

{% block content %}

&lt;h1&gt;{{ section.title }}&lt;/h1&gt;

{% for story in story_list %}
&lt;h2&gt;
  &lt;a href=&quot;{{ story.get_absolute_url }}&quot;&gt;
    {{ story.headline|upper }}
  &lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;{{ story.tease|truncatewords:&quot;100&quot; }}&lt;/p&gt;
{% endfor %}
{% endblock %}
</pre>
<div class="admonition-philosophie admonition">
<p class="first admonition-title">Philosophie</p>
<p>Pourquoi utiliser un template au format texte et non au format XML (comme
celui du TAL Zope) ? Nous voulions que le langage de template puisse être
utilisé pour plus que des templates XML/HTML. À World Online, nous
l'utilisons pour les mails, la JavaScript et le CSV. Vous pouvez utiliser le
langage de template pour tout format basé sur du texte.</p>
<p class="last">Oh, encore un truc : Rendre du XML éditable par les humains est sadique !</p>
</div>

</div>
<div class="section">
<h1><a id="variables" name="variables">Variables</a></h1>
<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
rencontre une variable, il évalue cette variable et la remplace par son
résultat.</p>
<p>Utilisez un point (<tt class="docutils literal"><span class="pre">.</span></tt>) pour accéder aux attributs d'une variable.</p>
<div class="admonition-en-coulisses admonition">

<p class="first admonition-title">En coulisses</p>
<p>Techniquement, lorsque le système de template rencontre un point, il
effectue les recherches suivantes, dans cet ordre :</p>
<blockquote class="last">
<ul class="simple">
<li>Dictionaire</li>
<li>Attribut</li>
<li>Appel de méthode</li>
<li>Index de liste</li>
</ul>
</blockquote>
</div>

<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
<tt class="docutils literal"><span class="pre">title</span></tt> de l'objet <tt class="docutils literal"><span class="pre">section</span></tt>.</p>
<p>Si vous utilisez une variable qui n'existe pas, le système de template va
insérer la valeur contenue dans le paramètre <tt class="docutils literal"><span class="pre">TEMPLATE_STRING_IF_INVALID</span></tt> qui
correspond par défaut à <tt class="docutils literal"><span class="pre">''</span></tt> (chaîne vide).</p>

<p>Lisez <a class="reference" href="#utiliser-les-r-f-rences-incluses">Utiliser les références incluses</a>, ci-dessous, pour vous aider à
connaître les variables disponibles pour un template donné.</p>
</div>
<div class="section">
<h1><a id="filtres" name="filtres">Filtres</a></h1>
<p>Vous pouvez modifier des variables lors de l'affichage en utilisant des
<strong>filtres</strong>.</p>
<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
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
convertit un texte en minuscule. Utilisez un pipe (<tt class="docutils literal"><span class="pre">|</span></tt>) pour appliquer un
filtre.</p>

<p>Les filtres peuvent « s'enchaîner ». La sortie d'un filtre est l'entrée du
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
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>
<p>Certains filtres possèdent des arguments. Un argument de filtre ressemble à :
<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
variable <tt class="docutils literal"><span class="pre">bio</span></tt>. Les arguments de filtres sont toujours entre double quotes.</p>

<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>
</div>
<div class="section">
<h1><a id="tags" name="tags">Tags</a></h1>
<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
variables : certains génèrent une sortie de texte, d'autres contrôlent le flux
grâce aux boucles ou à la logique, et certains chargent des informations
externes dans le template pouvant être utilisées par la suite.</p>

<p>Certains tags requièrent des tags de début et de fin (càd.
<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

<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
pouvez écrire vos propres tags si vous connaissez le Python.</p>
</div>
<div class="section">
<h1><a id="h-ritage-des-templates" name="h-ritage-des-templates">Héritage des templates</a></h1>
<p>La plus intéressante -- mais aussi la plus complexe -- partie du moteur de
template de Django est l'héritage. L'héritage des templates vous permet de
construire un template « squelette » de base contenant tous les éléments usuels
de votre site et définissant des blocs que les templates enfants pourront
écraser et/ou compléter.</p>
<p>Il est plus simple, pour comprendre l'héritage des templates, de commencer par
un exemple:</p>
<pre class="literal-block">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;
    &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;

&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot; /&gt;

    &lt;title&gt;{% block title %}Mon super site{% endblock %}&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;div id=&quot;sidebar&quot;&gt;
        {% block sidebar %}
        &lt;ul&gt;

            &lt;li&gt;&lt;a href=&quot;/&quot;&gt;Accueil&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;/blog/&quot;&gt;Blog&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;

        {% endblock %}
    &lt;/div&gt;

    &lt;div id=&quot;content&quot;&gt;
        {% block content %}{% endblock %}
    &lt;/div&gt;
&lt;/body&gt;
</pre>
<p>Ce template, que nous appelerons <tt class="docutils literal"><span class="pre">base.html</span></tt>, définit un simple squelette HTML
que vous pouvez utiliser pour une page à deux colonnes. C'est le boulot des
templates « enfants » de compléter les blocs vides avec du contenu.</p>

<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
enfants peuvent compléter. Tout ce que les tags <tt class="docutils literal"><span class="pre">block</span></tt> font c'est d'indiquer
au moteur de template qu'un template enfant peut écraser ces parties du
template.</p>
<p>Un template enfant pourrait ressembler à ça:</p>
<pre class="literal-block">
{% extends &quot;base.html&quot; %}

{% block title %}Mon super blog{% endblock %}

{% block content %}
{% for entry in blog_entries %}
    &lt;h2&gt;{{ entry.title }}&lt;/h2&gt;

    &lt;p&gt;{{ entry.body }}&lt;/p&gt;
{% endfor %}
{% endblock %}
</pre>
<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
template « étend » un autre template. Lorsque le système de template évalue ce
template, il commence par localiser le parent -- dans notre cas, « base.html ».</p>
<p>À ce moment, le moteur de template va tenir compte des trois tags

<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
template enfant. En fonction de la valeur de <tt class="docutils literal"><span class="pre">blog_entries</span></tt>, la sortie devrait
être proche de:</p>
<pre class="literal-block">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;

    &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot; /&gt;

    &lt;title&gt;Mon super blog&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;div id=&quot;sidebar&quot;&gt;
        &lt;ul&gt;

            &lt;li&gt;&lt;a href=&quot;/&quot;&gt;Accueil&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;/blog/&quot;&gt;Blog&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;

    &lt;/div&gt;

    &lt;div id=&quot;content&quot;&gt;
        &lt;h2&gt;Billet un&lt;/h2&gt;
        &lt;p&gt;C'est mon premier billet.&lt;/p&gt;

        &lt;h2&gt;Billet deux&lt;/h2&gt;
        &lt;p&gt;C'est mon second billet.&lt;/p&gt;
    &lt;/div&gt;
&lt;/body&gt;
</pre>

<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
valeur du template parent est utilisée à la place. Le contenu au sein d'un tag
<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>
<p>Vous pouvez utiliser autant de niveaux d'héritage que désiré. L'une des manières
habituelle d'utiliser l'héritage est l'approche à trois niveaux suivante :</p>
<blockquote>
<ul class="simple">
<li>Créez un template <tt class="docutils literal"><span class="pre">base.html</span></tt> qui définit l'apparence globale de votre
site.</li>

<li>Créez un template <tt class="docutils literal"><span class="pre">base_NOMDESECTION.html</span></tt> pour chaque section de votre
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
étendent tous <tt class="docutils literal"><span class="pre">base.html</span></tt> et incluent le style/design spécifique à la
section.</li>
<li>Créez un template individuel pour chaque type de page, comme les articles
de nouveautés ou les billets d'un blog. Ces templates étendent le template
de la section appropriée.</li>
</ul>
</blockquote>
<p>Cette approche maximise la réutilisation du code et rend facile l'ajout de blocs
partagés entre plusieurs parties du site comme la navigation.</p>

<p>Voici quelques astuces pour utiliser l'héritage :</p>
<blockquote>
<ul class="simple">
<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
premier tag du template. Dans le cas contraire l'héritage ne fonctionnera
pas.</li>
<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
base. Rappelez-vous, les templates enfants n'ont pas à redéfinir la
totalité des blocs, vous pouvez donc remplir les blocs avec un contenu
intéressant par défaut. Ne redéfinissez ensuite que ceux dont vous avez
besoin. Il vaut mieux en avoir plus que pas assez.</li>

<li>Si vous vous apercevez d'une duplication du contenu dans de nombreux
templates, cela signifie probablement que vous devriez déplacer ce contenu
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>
<li>Si vous avez besoin du contenu issu du template parent, la variable
<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
ajouter quelquechose au contenu parent existant au lieu de l'écraser.</li>

</ul>
</blockquote>
<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>
ayant le même nom dans le même template. Cette limitation existe car un tag
block fonctionne dans les deux directions. Cela signifie qu'un tag block ne
procure pas seulement un espace à compléter -- il définit aussi au niveau enfant
le contenu parent accessible dans cet espace (par <tt class="docutils literal"><span class="pre">block.super</span></tt>).</p>
</div>
<div class="section">
<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>L'interface d'administration de Django inclue une référence complète à
l'ensemble des tags et filtres de template disponibles pour un site donné. Pour
y accéder, rendez vous dans votre interface d'administration et cliquez sur le
lien « Documentation » en haut à droite de la page.</p>
<p>La référence est divisée en 4 sections : tags, filtres, modèles et vues.</p>
<p>Les sections <strong>tags</strong> et <strong>filtres</strong> décrivent tous les tags de base (en fait,
les références de tag et de filtre qui suivent proviennent directement de ces
pages) ainsi que vos propres bibliothèques de tags et de filtres disponibles.</p>
<p>La page des <strong>vues</strong> est la plus intéressante. Chaque URL de votre site a une
entrée distincte ici, et cliquer sur cette URL vous donnera accès :</p>

<blockquote>
<ul class="simple">
<li>Au nom de la fonction qui génère cette vue.</li>
<li>À une description succinte de ce que fait la vue.</li>
<li>Au <strong>contexte</strong>, ou une liste de variables accessibles dans le template de
la vue.</li>
<li>Au nom du ou des template(s) qui est(sont) utilisé(s) pour cette vue.</li>
</ul>
</blockquote>
<p>Chaque page de documentation d'une vue dispose aussi d'un bookmarklet que vous
pouvez utiliser pour aller directement de n'importe quelle page à la page de
documentation de cette vue.</p>
<p>Les sites propulsés par Django utilisant généralement des objets de base de
données, la section <strong>modèles</strong> de la page de documentation décrit chaque type
d'objet dans le système courant avec l'ensemble des champs disponibles dans cet
objet.</p>

<p>L'ensemble des pages de documentation vous renseigne sur chaque tag, filtre,
variable et objet disponible pour un template donné.</p>
</div>
<div class="section">
<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>
<p>Certaines applications procurent des tags personnalisés et des bilbiothèques de
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>
<pre class="literal-block">
{% load comments %}

{% comment_form for blogs.entries entry.id with is_public yes %}
</pre>

<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
rend ensuite le tag <tt class="docutils literal"><span class="pre">comment_form</span></tt> utilisable. Consultez la rubrique
documentation de votre interface d'administration pour trouver la liste des
bibliothèques personnalisées de votre installation.</p>
<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,
séparés par des espaces. Exemple:</p>

<pre class="literal-block">
{% load comments i18n %}
</pre>
<div class="section">
<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>
<p>Lorsque vous chargez un tag personnalisé ou une bibliothèque de filtres, les
tags/filtres ne sont accessibles qu'au sein du template courant -- et aucun des
templates parents ou enfants issus de l'héritage des templates n'y a accès.</p>
<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
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
aux filtres et tags du template comments. Le template enfant doit avoir son
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>

<p>C'est une fonctionnalité pour la maintenabilité et l'intégrité des templates.</p>
</div>
</div>
<div class="section">
<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>
<p>Pour ceux ne disposant pas d'une interface d'administration, la référence des
tags et filtres suit. En raison de la personnalisation possible de Django, la
référence dans votre administration prévaut sur celle-ci concernant
l'accessibilité et la fonction des tags et filtres.</p>
<div class="section">
<h2><a id="r-f-rence-des-tags-inclus" name="r-f-rence-des-tags-inclus">Référence des tags inclus</a></h2>
</div>
<div class="section">
<h2><a id="r-f-rence-des-filtres-inclus" name="r-f-rence-des-filtres-inclus">Référence des filtres inclus</a></h2>
<p><strong>La suite de la traduction est en cours</strong>, j'ai jugé qu'il était plus important
de publier cette première partie qui pose les bases en attendant. Il faut avouer
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>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
documentation de Django</a>.</p>
<p>Cette traduction correspond à la révision 3589 (post 0.95).</p>
</div>
</div>
