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 Smarty ou CheetahTemplate, vous n'aurez aucune difficulté à adopter les templates Django.
Templates
Un template est un simple fichier texte. Il peut générer n'importe quel type de fichier texte (HTML, XML, CSV, etc).
Un template contient des variables qui seront remplacées par leurs valeurs lors de son évaluation et des tags qui controlent la logique du template.
Ci-dessous un template minimal qui illustre les bases. Chaque élément sera expliqué plus tard dans ce document.:
{% extends "base_generic.html" %}
{% block title %}{{ section.title }}{% endblock %}
{% block content %}
<h1>{{ section.title }}</h1>
{% for story in story_list %}
<h2>
<a href="{{ story.get_absolute_url }}">
{{ story.headline|upper }}
</a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
{% endfor %}
{% endblock %}
Philosophie
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.
Oh, encore un truc : Rendre du XML éditable par les humains est sadique !
Variables
Les variables ressemblent à {{ variable }}. Lorsque le moteur de template rencontre une variable, il évalue cette variable et la remplace par son résultat.
Utilisez un point (.) pour accéder aux attributs d'une variable.
En coulisses
Techniquement, lorsque le système de template rencontre un point, il effectue les recherches suivantes, dans cet ordre :
- Dictionaire
- Attribut
- Appel de méthode
- Index de liste
Dans le précédent exemple, {{ section.title }} sera remplacé par l'attribut title de l'objet section.
Si vous utilisez une variable qui n'existe pas, le système de template va insérer la valeur contenue dans le paramètre TEMPLATE_STRING_IF_INVALID qui correspond par défaut à '' (chaîne vide).
Lisez Utiliser les références incluses, ci-dessous, pour vous aider à connaître les variables disponibles pour un template donné.
Filtres
Vous pouvez modifier des variables lors de l'affichage en utilisant des filtres.
Les filtres ressemblent à {{ name|lower }}. Ceci affiche la valeur de la variable {{ name }} après avoir été filtrée par le filtre lower, qui convertit un texte en minuscule. Utilisez un pipe (|) pour appliquer un filtre.
Les filtres peuvent « s'enchaîner ». La sortie d'un filtre est l'entrée du suivant. {{ text|escape|linebreaks }} est souvent utilisé pour échapper le contenu d'un texte et convertir ensuite les sauts de lignes en tags <p>.
Certains filtres possèdent des arguments. Un argument de filtre ressemble à : {{ bio|truncatewords:"30" }}. Cela va afficher les 30 premiers mots de la variable bio. Les arguments de filtres sont toujours entre double quotes.
La Référence des filtres inclus ci-dessous décrit l'ensemble des ces filtres.
Tags
Les tags ressemblent à : {% tag %}. 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.
Certains tags requièrent des tags de début et de fin (càd. {% tag %} ... contenu du tag ... {% endtag %}). La Référence des tags inclus ci-dessous décris l'ensemble de ces tags. Vous pouvez écrire vos propres tags si vous connaissez le Python.
Héritage des templates
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.
Il est plus simple, pour comprendre l'héritage des templates, de commencer par un exemple:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>{% block title %}Mon super site{% endblock %}</title>
</head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li><a href="/">Accueil</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
{% endblock %}
</div>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
Ce template, que nous appelerons base.html, 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.
Dans cet exemple, le tag {% block %} définit trois blocs que les templates enfants peuvent compléter. Tout ce que les tags block font c'est d'indiquer au moteur de template qu'un template enfant peut écraser ces parties du template.
Un template enfant pourrait ressembler à ça:
{% extends "base.html" %}
{% block title %}Mon super blog{% endblock %}
{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
Le tag {% extends %} 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 ».
À ce moment, le moteur de template va tenir compte des trois tags {% block %} dans base.html et remplacer ces blocs avec le contenu du template enfant. En fonction de la valeur de blog_entries, la sortie devrait être proche de:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>Mon super blog</title>
</head>
<body>
<div id="sidebar">
<ul>
<li><a href="/">Accueil</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
</div>
<div id="content">
<h2>Billet un</h2>
<p>C'est mon premier billet.</p>
<h2>Billet deux</h2>
<p>C'est mon second billet.</p>
</div>
</body>
Notez que tant que le template enfant ne redéfinit pas le bloc sidebar, la valeur du template parent est utilisée à la place. Le contenu au sein d'un tag {% block %} dans un template parent est toujours utilisé en dernier lieu.
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 :
- Créez un template base.html qui définit l'apparence globale de votre site.
- Créez un template base_NOMDESECTION.html pour chaque section de votre site. Par exemple, base_news.html, base_sports.html. Ces templates étendent tous base.html et incluent le style/design spécifique à la section.
- 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.
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.
Voici quelques astuces pour utiliser l'héritage :
- Si vous utilisez {% extends %} dans un template, ça doit être le premier tag du template. Dans le cas contraire l'héritage ne fonctionnera pas.
- Il vaut mieux avoir de nombreux tags {% block %} 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.
- 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 {% block %} au sein d'un template parent.
- Si vous avez besoin du contenu issu du template parent, la variable {{ block.super }} est là pour ça. C'est intéressant si vous souhaitez ajouter quelquechose au contenu parent existant au lieu de l'écraser.
Pour finir, notez l'impossibilité de définir plusieurs tags {% block %} 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 block.super).
Utiliser les références incluses
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.
La référence est divisée en 4 sections : tags, filtres, modèles et vues.
Les sections tags et filtres 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.
La page des vues 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 :
- Au nom de la fonction qui génère cette vue.
- À une description succinte de ce que fait la vue.
- Au contexte, ou une liste de variables accessibles dans le template de la vue.
- Au nom du ou des template(s) qui est(sont) utilisé(s) pour cette vue.
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.
Les sites propulsés par Django utilisant généralement des objets de base de données, la section modèles 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.
L'ensemble des pages de documentation vous renseigne sur chaque tag, filtre, variable et objet disponible pour un template donné.
Tags personnalisés et bilbiothèques de filtres
Certaines applications procurent des tags personnalisés et des bilbiothèques de filtres. Pour y accéder dans un template, utilisez le tag {% load %}:
{% load comments %}
{% comment_form for blogs.entries entry.id with is_public yes %}
Ci-dessus, le tag load charge la bibliothèque de tags comments, ce qui rend ensuite le tag comment_form utilisable. Consultez la rubrique documentation de votre interface d'administration pour trouver la liste des bibliothèques personnalisées de votre installation.
Le tag {% load %} peut prendre plusieurs noms de bibliothèques à la fois, séparés par des espaces. Exemple:
{% load comments i18n %}
Bibliothèques personnalisées et héritage des templates
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.
Par exemple, si un template foo.html a {% load comments %}, un template enfant (par exemple, un qui a {% extends "foo.html" %}) n'aura pas accès aux filtres et tags du template comments. Le template enfant doit avoir son propre {% load comments %}.
C'est une fonctionnalité pour la maintenabilité et l'intégrité des templates.
Référence des tags et filtres inclus
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.
Référence des filtres inclus
La suite de la traduction est en cours, j'ai jugé qu'il était plus important de publier cette première partie qui pose les bases en attendant. Il faut avouer que la suite (en) est moins passionnante...
Vous pouvez maintenant retourner à la page d'accueil des traductions de la documentation de Django.
Cette traduction correspond à la révision 3589 (post 0.95).
Commentaires
waaaoou merci beaucoup! J'en suis a mes premiers babultiements en Python et je voulais justement utiliser django pour un projet web personnel!
1 | Bernard, le 16 August 2006 à 13h
www.djangobook.com/en/bet...
-> www.djangobook.com/fr/bet...
:D a mission for biologeek !
2 | djangofan, le 13 November 2006 à 11h
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.
J'ai essayé :
<img src="{{ annonce.photo[1].url }}" width="120" height="90" />
<img src="{{ annonce.photo(1).url }}" width="120" height="90" />
mais ça fonctionne pas. Une idée de la syntaxe à utiliser ?
Merci
3 | djangofan, le 13 November 2006 à 13h
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 :
www.djangoproject.com/doc...
ps : et pour le djangobook c'est en cours de réflexion ;-).
4 | David, biologeek, le 13 November 2006 à 16h
En fait c'est pas ça, d'ailleurs quand je me relis, c'est pas clair. :-D
Ce que je voudrais en faite c'est acceder à la valeur de la propriété url de la classe photo. Elle meme est une "sous-classe" de la classe annonce.
Je sais pas si je suis bien compréhensible !
5 | djangofan, le 13 November 2006 à 17h
Pas vraiment :D
Il y a un moyen que tu me colles ton model quelquepart (ou par mail ?)
6 | David, biologeek, le 13 November 2006 à 21h
Bonjour,
Voilà une petite question qui se pose !
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?
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.
Merci
7 | DjangoJO, le 21 December 2006 à 15h
Il y a trois solutions :
* soit tu passes par les vues génériques et dans ce cas il faut lire l'article de James www.b-list.org/weblog/200...
* soit tu mets tout ce dont tu as besoin dans le dictionnaire permettant que tu passes à ta vue.
* soit tu utilises les templatetags, une explication sur b-list aussi (site de référence) : www.b-list.org/weblog/200....
Tu peux m'envoyer ton code si tu veux plus d'explications.
8 | David, biologeek, le 21 December 2006 à 23h
J'ai un champs :
CV = models.FileField("CV ", upload_to="candidats/", blank=True)
Et dans mon template je fait :
<input type="file" size=55 maxlength=100000 name="CV" id="id_CV">
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"candidats" le CV!!!
(( ce qui marche bien sur si je rajoute une candidature à la main dans la partie administration.
Quelqu'un pourrai m'aider SVP.
Merci
9 | djangofan2, le 21 February 2007 à 10h
@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).
10 | David, biologeek, le 21 February 2007 à 11h
Bonjour,
J'aimerai tout simplement savoir si il est possible d'utiliser le search_field de la partie admin de django dans un template personnel ?
A part si bien sûr, il existe un module de recherche de django ? ou bien alors il faut le faire soit même ?
Comme on peut le voir sur la plus part des sites internet il y a toujours une zone recherche ...
Merci
11 | DjangoFan2, le 26 February 2007 à 11h
@DjangoFan2 : c'est une vue à coder soit-même car elle est très spécifique de l'application développée.
12 | David, biologeek, le 26 February 2007 à 12h
Merci,
Bien je vais m'y mettre sans trop tarder alors !!!
Et juste pour savoir ::
- 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 ?
- L'utilisation d'ajax est-il possible ? si oui comment faire pour inclure un fichier (exemple en php :<? include("menu.php");?>
Merci beaucoup pour tous ses renseignements !!!
13 | DjangoFan2, le 26 February 2007 à 12h
> 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 ?
Il doit y avoir un conflit entre les variables js de tes deux fichiers (?)
> L'utilisation d'ajax est-il possible ?
Bien sûr !
> si oui comment faire pour inclure un fichier (exemple en php :<? include("menu.php");?>
Ça c'est de l'héritage de template, pas de l'AJAX. cf le billet de Jeff Croft : www2.jeffcroft.com/blog/2...
14 | David, biologeek, le 26 February 2007 à 14h
Merci beaucoup pour le tuto, c'est très clair et bien expliqué .
Par contre j'aimerai savoir si c'est possible de comparer une variable dans les "if" ( exemple : {% if cpt=2 %} ou faire le même style d'opération comme en php.
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.
Merci beaucoup
Et encore bravo pour le site
15 | djangoNew, le 28 February 2007 à 15h
Il existe ifequal pour ça : {% ifequal cpt 2 %}
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...
Bienvenue dans l'univers Django :-)
16 | David, biologeek, le 28 February 2007 à 18h
Me revoilà pour d'autre petites questions sur des choses que je n'ai pas trop trop compris !
Merci encore pour toutes ses explications !
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 !!!
J'ai compris l'histoire des templates car c'est très bien expliqué mais là je suis un peu perdu !
MERCI d'avance
17 | djangoNew, le 2 March 2007 à 15h
Il suffit de faire un {% extends "base.html" %} en première ligne de ton template. Si tu veux tu peux regarder ce que ça donne pour le site de django-fr.org : trac.django-fr.org/trac/b...
18 | David, biologeek, le 3 March 2007 à 12h
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.
Je me suis peut être mal exprimé la derniére fois !
La seule action qui déclenche une view c'est l'url en question (a ce que j'ai compris).
Si je veux afficher les articles de mon module et les contacts de mon autre module normalement il faut que j'appele la view "Articles" et la view "Contact" avec leurs url respectif ( genre : www.monsite/article et www.monsite/contact) !
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.
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'"extends" de base.html mais comment faire pour que je puisse aussi appelé la view de contact et l'extends de base.html ??
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 ...
19 | djangoNew, le 5 March 2007 à 10h
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.
20 | David, biologeek, le 5 March 2007 à 14h
Ajouter un commentaire