Skip to content

Latest commit

 

History

History
120 lines (92 loc) · 4.08 KB

4. Django Template Language.md

File metadata and controls

120 lines (92 loc) · 4.08 KB

Motivazione

Scrivere pagine web a mano (codice HTML) implicherebbe tenere traccia dell'apertura e chiusura di tag. Nel caso in cui si sbagli la sintassi, non vengono sollevati messaggi di errore, semplicemente si visualizza la formattazione sbagliata.

Inoltre, violerebbero il principio DRY, principio cardine di Django.

Infine, la generazione di pagine potrebbe dover essere dinamica; ma le pagine HTML sono intrinsecamente statiche.

DTL - Django Template Language

Nasce su questi presupposti il DTL, un'estensione del linguaggio HTML, che permette al programmatore di inserire business logic arbitraria all'interno della vista della pagina.

Linguaggio basato si blocchi anziché su tag. Mix tra linguaggio di markup e di programmazione.

I file DTL appaiono come file sorgenti statici, ma vengono elaborati dinamicamente lato server.

Template engine

Il template engine di Django si occupa di parsare il template, generare un context, gestire tag, eseguire codice dinamico, per generare una pagina HTML come prodotto della "compilazione".

Il backend del template engine di un progetto Django è configurabile. Può supportare Jinga2 o DTL.

La configurazione avviene mediante settings.TEMPLATES:

TEMPLATES = [
	 {
		 'BACKEND': 'django.template.backends.django.DjangoTemplates',
		 ...
	 }
]

Ogni applicazione gestita dal progetto può avere un proprio template.

Tra le OPTIONS possiamo trovare la chiave context_processors, che rappresenta i contesti a cui ha accesso il template engine. #Rivedi

Internals

Il modulo django.template.loader fornisce i seguenti metodi: - get_template(template_name, name=None) -> Template

  • select_template(template_name_list, using=None) come sopra ma accetta una lista
  • render_to_string(template_name, context=None, request=None, using=None) renderizza un template

#Attenzione in caso di errore, nota in quale metodo è stato sollevato. Eg. nell'ultimo caso il problema potrebbe risiedere nella scorretta sintassi con cui è stato scritto il template.

Noi ci interfacceremo solamente con il metodo render(...)

Template Language

Variable

{{ variable.attribute }}

Il nome dell'attributo viene risolto nel seguente ordine:

  • chiave di un dizionario
  • attributo o un metodo
  • indice numerico

Se l'attributo è un metodo chiamabile, viene chiamato senza parametri in ingresso e il valore ritornato viene sostituito allo statament.

Tempalte filters

{{ name|lower }}
{{ var|filter|another_filter }}
{{ text|truncatewords:30 }}

#Vedi reference template filters

Costrutti condizionali e iterativi

{% for user in userbase %}
	{{ user.name }} <br>
{% endfor %}
{% if %}
	{{ user in admins }}
{% endif %}

Placeholder

<html>
<head>
...
<title> {% block head %} {% endblock %} </title>
</head>

<body> {% block body %} {% endblock %} </body>
</html>

URL alias

Perché usare gli alias (campo name del path)? perché è invariante rispetto al cambio dell'endpoint. Inoltre funziona con type enforcing e path parametrizzati.

L'href può essere ottenuto con il tag per la risoluzione {% url 'welcomepath' nome='mario' eta=25 %}.

Template inheritance

Come in Java e Python, esiste super per chiamare metodi o attributi della classe padre. A differenza di Java, può essere chiamato anche al di fuori del costruttore.

Per ottenere il contenuto di un blocco, dal padre della gerarchia, possiamo fare:

{% block content %}
	{{ block.super }}
	Continue content block.
{% endblock %}

Accesso alla richiesta da template

Per esempio, possiamo ottenere il nome passato al path parametrico con:

{{ request.resovler_match.kwargs.nome }}

Oppure:

{{ request.GET. name }}

#Attenzione l'uso scorretto di queste sostituzioni porta spesso al template-injection, reflected XSS, etc.

#Vedi server-side template injection - SSTI. Sembra non essere un problema con un corretto rendering del template. Nell'esempio proposto non viene fatta distinzione (problema architetturale) tra template e data.

#Nota i commenti in DTL si fanno con {# tag #}