Tutos Django

L'encapsulation des Templates

Comme tout bon framework MVC, Django gère l'héritage des templates et met donc en avant le principe DRY (Don't Repeat Yourself).
Nous allons voir quels tags nous permettent de gérer correctement une application, sans avoir à réécrire incessamment du code.
Pour cela, nous allons créer une nouvelle application que nous appèlerons 'myapp'.
Placez-vous dans votre projet et exécutez la commande (pour créer un projet, reportez-vous à ce tutoriel) : 

$ python manage.py startapp myapp

Positionnez-vous dans le dossier 'myapp' ainsi produit, et créez un répertoire templates ainsi que les fichiers 'skeleton.html', 'index.html', 'about.html', 'header.html', 'footer.html' :

$ cd myapp
$ mkdir templates
$ cd templates
$ touch skeleton.html index.html about.html header.html footer.html

Nous allons à présent éditer le fichier skeleton.html comme ceci :

<!DOCTYPE HTML>
<html>
  <head>
    <title>My App</title>
    {% block css %}
    {% endblock %}
    {% block js %}
    {% endblock %}
  </head>
  <body>
    <div id="container" >
      <div id="header">
        {% block header %}
        {% include "header.html" %}
        {% endblock %}
      </div>
      <div id="content">
        {% block content %}
        <h3>Voici mon application : </h3>
        {% endblock %}
      </div>
      <div id="footer">
        {% block footer %}
        {% include "footer.html" %}
        {% endblock %}
      </div>
    </div>
  </body>
</html>

Nous venons donc de créer un fichier HTML valide HTML5 qui contient certains tags bien spécifiques.
Juste avant de passer à l'explication de ces tags, nous allons remplir les autres fichiers html.

header.html :

<h1>Header</h1>

footer.html :

<h1>Footer</h1>

index.html :

{% extends "skeleton.html" %}

{% block content %}
<h2>Ceci est la page d'accueil de l'application</h2>
{% endblock %}

about.html :

{% extends "skeleton.html" %}

{% block content %}
{{ block.super }}
<p>A propos de l'application.</p>
{% endblock %}

Vous remarquez que nous utilisons les tags extends, block et include principalement !
Le tag {% extends %} est la clef 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, « skeleton.html ».

À ce moment, le moteur de template va tenir compte des cinq tags {% block %} dans skeleton.html.
Il est alors possible de remplacer ce qui est contenu dans un block en le redéclarant dans le template enfant. Ce qui est le cas d'index.html.
Si nous avions voulu conserver ce qui est dans le block du template parent, nous devons utiliser {{ block.super }}  qui permet de rajouter des éléments au block du template parent, comme c'est le cas d'about.html.

Dans ces deux exemples, nous ne montrons que le remplacement du block content mais il aurait été également possible de redéfinir les block css, js, header et footer. Ce qui peut-être pratique par exemple dans le cas du chargement de fichiers medias propres à une seule page, menant à une optimisation des performances de votre Web Application.

Nous découvrons aussi le tag include qui va se charger d'inclure le fichier passé en paramètre afin de l'interpréter dans le template. Cela permet de découper facilement notre code et permet une meilleure maintenance de celui-ci. Vous vous apercevez que j'ai délibérément inclus ces fichiers dans des block afin qu'il nous soit toujours possible de les modifier dans les templates enfant, ou bien d'y rajouter des informations.

Voyons ce que produit le code que nous avons écrit...
 Pour cela, n'oubliez pas de modifier le fichier 'settings.py' de votre projet pour y inclure le chemin vers notre dossier de templates et renseigner notre nouvelle application :

TEMPLATE_DIRS = (
#   '/home/gcisco/tmp/mysite/helloworld/templates',
    '/home/gcisco/tmp/mysite/myform/templates',
    '/home/gcisco/tmp/mysite/myapp/templates',
)

INSTALLED_APPS = (
    'django.contrib.auth',
    ....
    #'helloworld',
    'myform',
    'myapp',
)

Remarquez que je commente ici le dossier de templates de mon application helloworld (créée dans notre tout premier tutoriel), afin d'éviter tout possible conflit.
Je mets à présent à jour mon fichier urls.py :

#urlpatterns = patterns('',                                                                                                                                                                                          
#                       url(r'^$', 'mysite.helloworld.views.home', name='home'),                                                                                                                                     
#                       url(r'^sondage$', 'mysite.helloworld.views.sondage', name='sondage'),                                                                                                                        
#)

urlpatterns = patterns('mysite.myapp.views',
                        url(r'^$', 'index', name='index'),
                        url(r'^about$', 'about', name='about'),
)

Là aussi je commente les urls concernant l'application 'helloworld' afin d'éviter tout conflit (mon projet ici est nommé 'mysite', n'oubliez pas de changer avec le nom de votre propre projet).

La dernière chose à faire et de renseigner le fichier views.py de notre application 'myapp' :

from django.shortcuts import render_to_response

def index(request):
    return render_to_response('index.html')

def about(request):
    return render_to_response('about.html')

Testons à présent !

$ python manage.py runserver

Dirigez-vous à l'adresse http://127.0.0.1:8000/ vous devriez voir ceci :

Index

Si vous vous dirigez sur : http://127.0.0.1:8000/about :

About

Nous obtenons bien le comportement attendu ! Vous remarquez que le header et le footer sont bien chargés et que dans le cas d'index.html, le contenu du block content est remplacé alors que dans celui d'about.html, nous rajoutons de l'information à ce container.

Voilà ! vous savez à présent comment gérer l'héritage des templates en suivant le principe DRY !

Nous avons vu ici un exemple d'héritage père-fils, mais il n'y a pas de limites aux générations, vous pouvez par exemple créer une relation grand-père/père/fils en rajoutant des block dans le père et en déclarant un tag extends relié au père dans le fils.

Article suivant

Article précédent

Articles associés

Articles similaires

Commentaires

Les commentaires sont fermés.

Pingbacks

Les pingbacks sont fermés.