gwift-book/source/part-3-data-model/templates.adoc

183 lines
5.3 KiB
Plaintext
Raw Normal View History

2020-04-13 15:01:36 +02:00
== Templates
2015-12-21 21:43:55 +01:00
2020-04-13 15:01:36 +02:00
=== Structure et configuration
2020-02-17 20:45:39 +01:00
==== Répertoires de découverte des templates
2020-02-17 20:45:39 +01:00
[source,bash]
----
$ tree templates/
templates/
└── wish
└── list.html
----
2022-03-10 18:36:01 +01:00
Par défaut, Django cherchera les templates dans les répertoirer d'installation.
Vous devrez vous éditer le fichier `gwift/settings.py` et ajouter, dans la variable `TEMPLATES`, la clé `DIRS` de la manière suivante:
2020-02-17 20:45:39 +01:00
[source,python]
----
TEMPLATES = [
{
...
'DIRS': [ 'templates' ],
...
},
]
----
2022-03-10 18:36:01 +01:00
==== Fichiers statiques
(à compléter)
2020-04-13 15:01:36 +02:00
=== Builtins
2020-02-17 20:45:39 +01:00
Django vient avec un ensemble de *tags* ou *template tags*. On a vu la boucle `for` ci-dessus, mais il existe https://docs.djangoproject.com/fr/1.9/ref/templates/builtins/[beaucoup d'autres tags nativement présents]. Les principaux sont par exemple:
2020-02-17 20:45:39 +01:00
* `{% if ... %} ... {% elif ... %} ... {% else %} ... {% endif %}`: permet de vérifier une condition et de n'afficher le contenu du bloc que si la condition est vérifiée.
* Opérateurs de comparaisons: `<`, `>`, `==`, `in`, `not in`.
* Regroupements avec le tag `{% regroup ... by ... as ... %}`.
2020-04-13 15:01:36 +02:00
* `{% url %}` pour construire facilement une URL à partir de son nom
* `urlize` qui permet de remplacer des URLs trouvées dans un champ de type CharField ou TextField par un lien cliquable.
2020-02-17 20:45:39 +01:00
* ...
2020-04-13 15:01:36 +02:00
Chacune de ces fonctions peut être utilisée autant au niveau des templates qu'au niveau du code. Il suffit d'aller les chercher dans le package `django.template.defaultfilters`. Par exemple:
[source,python]
----
from django.db import models
from django.template.defaultfilters import urlize
class Suggestion(models.Model):
2020-04-13 15:01:36 +02:00
"""Représentation des suggestions.
"""
subject = models.TextField(verbose_name="Sujet")
def urlized_subject(self):
"""
Voir https://docs.djangoproject.com/fr/3.0/howto/custom-template-tags/
"""
return urlize(self.subject, autoescape=True)
2022-03-10 18:36:01 +01:00
2020-04-13 15:01:36 +02:00
----
2022-03-10 18:36:01 +01:00
==== Regroup By
(le truc super facile qui sert à mort dans plein de cas sans qu'on n'ait à se casser la tête).
2020-04-13 15:01:36 +02:00
=== Non-builtins
En plus des quelques tags survolés ci-dessus, il est également possible de construire ses propres tags. La structure est un peu bizarre, car elle consiste à ajouter un paquet dans une de vos applications, à y définir un nouveau module et à y définir un ensemble de fonctions. Chacune de ces fonctions correspondra à un tag appelable depuis vos templates.
2022-03-10 18:36:01 +01:00
Il existe trois types de tags *non-builtins*:
2022-03-10 18:36:01 +01:00
1. *Les filtres* - on peut les appeler grâce au *pipe* `|` directement après une valeur dans le template.
2020-04-13 15:01:36 +02:00
2. *Les tags simples* - ils peuvent prendre une valeur ou plusieurs en paramètre et retourne une nouvelle valeur. Pour les appeler, c'est *via* les tags `{% nom_de_la_fonction param1 param2 ... %}`.
3. *Les tags d'inclusion*: ils retournent un contexte (ie. un dictionnaire), qui est ensuite passé à un nouveau template. Type `{% include '...' ... %}`.
Pour l'implémentation:
2022-03-10 18:36:01 +01:00
1. On prend l'application `wish` et on y ajoute un répertoire `templatetags`, ainsi qu'un fichier `__init__.py`.
2020-02-17 20:45:39 +01:00
2. Dans ce nouveau paquet, on ajoute un nouveau module que l'on va appeler `tools.py`
3. Dans ce module, pour avoir un aperçu des possibilités, on va définir trois fonctions (une pour chaque type de tags possible).
2020-04-13 15:01:36 +02:00
2020-02-17 20:45:39 +01:00
[source,bash]
----
[Inclure un tree du dossier template tags]
----
2020-04-13 15:01:36 +02:00
Pour plus d'informations, la https://docs.djangoproject.com/en/stable/howto/custom-template-tags/#writing-custom-template-tags[documentation officielle est un bon début].
==== Filtres
2020-02-17 20:45:39 +01:00
[source,python]
----
# wish/tools.py
2022-03-10 18:36:01 +01:00
2020-02-17 20:45:39 +01:00
from django import template
2020-02-17 20:45:39 +01:00
from wish.models import Wishlist
2020-02-17 20:45:39 +01:00
register = template.Library()
2020-02-17 20:45:39 +01:00
@register.filter(is_safe=True)
def add_xx(value):
return '%sxx' % value
2020-04-13 15:01:36 +02:00
----
==== Tags simples
[source,python]
----
# wish/tools.py
2022-03-10 18:36:01 +01:00
2020-04-13 15:01:36 +02:00
from django import template
from wish.models import Wishlist
register = template.Library()
2020-02-17 20:45:39 +01:00
@register.simple_tag
def current_time(format_string):
return datetime.datetime.now().strftime(format_string)
2020-04-13 15:01:36 +02:00
----
==== Tags d'inclusion
[source,python]
----
# wish/tools.py
2022-03-10 18:36:01 +01:00
2020-04-13 15:01:36 +02:00
from django import template
from wish.models import Wishlist
register = template.Library()
2020-02-17 20:45:39 +01:00
@register.inclusion_tag('wish/templatetags/wishlists_list.html')
def wishlists_list():
2022-03-10 18:36:01 +01:00
return { 'list': Wishlist.objects.all() }
2020-02-17 20:45:39 +01:00
----
2020-04-13 15:01:36 +02:00
2022-03-10 18:36:01 +01:00
=== Contexts Processors
2022-03-10 18:36:01 +01:00
Un `context processor` permet d'ajouter des informations par défaut à un contexte (le dictionnaire qu'on passe de la vue au template).
2022-03-10 18:36:01 +01:00
L'idée est d'ajouter une fonction à un module Python à notre projet, puis de le référencer parmi
les CONTEXT_PROCESSORS de nos paramètres généraux. Cette fonction doit peupler un dictionnaire, et les clés de ce dictionnaire seront
directement ajoutées à tout autre dictionnaire/contexte passé à une vue. Par exemple:
(cf. https://stackoverflow.com/questions/60515797/default-context-for-all-pages-django[StackOverflow] - à retravailler)
2022-03-10 18:36:01 +01:00
[source,python]
----
from product.models import SubCategory, Category
def add_variable_to_context(request):
return {
'subCategories': SubCategory.objects.order_by('id').all(),
'categories': Category.objects.order_by("id").all(),
}
----
2022-03-10 18:36:01 +01:00
[source,python]
----
'OPTIONS': {
'context_processors': [
....
'core.context_processors.add_variable_to_context',
....
],
},
----