{"title":"Come creare tag di template e filtri personalizzati","version":"4.1","locale":"it","docname":"howto/custom-template-tags","url":"/it/4.1/howto/custom-template-tags/","canonical":"https://djangodocs.dev/it/4.1/howto/custom-template-tags/","summary":"Il linguaggio di template di Django arriva come un’ampia varietà di filtri e tag built-in progettati per far fronte alle necessità di logica di presentazione delle…","html":"<h1>Come creare tag di template e filtri personalizzati<a class=\"heading-anchor\" href=\"#how-to-create-custom-template-tags-and-filters\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Il linguaggio di template di Django arriva come un’ampia varietà di <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/\"><span class=\"doc\">filtri e tag built-in</span></a> progettati per far fronte alle necessità di logica di presentazione delle tue applicazioni. Eppure, potresti trovarti nella condizione di aver bisogno di funzionalità che non sono coperte dal set di primitive di template del core. Puoi estendere il motore di template definendo dei tag e filtri personalizzati usando Python e poi renderli disponibili ai tuoi template utilizzando il tag <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/#std-templatetag-load\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">load</span> <span class=\"pre\">%}</span></code></a></p>\n<section id=\"code-layout\">\n<h2>Layout del codice<a class=\"heading-anchor\" href=\"#code-layout\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Il posto più comune in cui specificare tag e filtri di template personalizzati è nell’applicazione Django. Se sono collegati ad una app esistente, ha senso metterli lì; altrimento, possono essere aggiunti ad una nuova app. Quando una applicazione Django viene aggiunta ad <a class=\"reference internal\" href=\"/it/4.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">INSTALLED_APPS</span></code></a>, ogni tag che definisce nella locazione convenzionale descritta qui sotto viene automaticamente reso disponibile al caricamento nei template.</p>\n<p>L’applicazione deve contenere una directory <code class=\"docutils literal notranslate\"><span class=\"pre\">templatetags</span></code>, allo stesso livello di <code class=\"docutils literal notranslate\"><span class=\"pre\">models.py</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">views.py</span></code>, ecc. Se non esiste già, creala - non dimenticare il file <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__.py</span></code> per assicurarti che la directory sia trattata come un package Python.</p>\n<aside class=\"admonition-development-server-won-t-automatically-restart admonition\">\n<p class=\"admonition-title\">I server di sviluppo non si riavviano in automatico</p>\n<p>Dopo aver aggiunto il modulo <code class=\"docutils literal notranslate\"><span class=\"pre\">templatetags</span></code>, avrai bisogno di riavviare il tuo server prima di poter utilizzare i tag o i filtri nei template.</p>\n</aside>\n<p>I tuoi tag e filtri personalizzati vivranno in un modulo nella directory <code class=\"docutils literal notranslate\"><span class=\"pre\">templatetags</span></code>. Il nome del file del modulo è il nome che userai per caricare successivamente i tag, quindi fai attenzione a sceglierne uno che non vada in conflitto con i tag ed i filtri personalizzati di un’altra applicazione.</p>\n<p>Per esempio, se i tags/filtri personalizzati sono in un file chiamato <code class=\"docutils literal notranslate\"><span class=\"pre\">poll_extras.py</span></code>, il layout della tua applicazione potrebbe assomigliare a questo:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">polls</span><span class=\"o\">/</span>\n    <span class=\"fm\">__init__</span><span class=\"o\">.</span><span class=\"n\">py</span>\n    <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">py</span>\n    <span class=\"n\">templatetags</span><span class=\"o\">/</span>\n        <span class=\"fm\">__init__</span><span class=\"o\">.</span><span class=\"n\">py</span>\n        <span class=\"n\">poll_extras</span><span class=\"o\">.</span><span class=\"n\">py</span>\n    <span class=\"n\">views</span><span class=\"o\">.</span><span class=\"n\">py</span>\n</code></pre></div>\n<p>E nel tuo template utilizzerai i seguenti:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">load</span> <span class=\"nv\">poll_extras</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Le app che contengono i tag personalizzati devono trovarsi in <a class=\"reference internal\" href=\"/it/4.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">INSTALLED_APPS</span></code></a> affinchè il tag <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/#std-templatetag-load\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">load</span> <span class=\"pre\">%}</span></code></a> funzioni. E” una feature di sicurezza: ti rende possibile fare hosting di codice Python per molte librerie di template su una singola macchina host senza abilitare l’accesso a tutte per ogni installazione di Django.</p>\n<p>Non c’è limite al numero di moduli che puoi aggiungere nel package <code class=\"docutils literal notranslate\"><span class=\"pre\">templatetags</span></code>. Tieni solo presente che uno statement <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/#std-templatetag-load\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">load</span> <span class=\"pre\">%}</span></code></a> caricherà tag/filtri per un dato nome di modulo Python, non per il nome dell’app.</p>\n<p>Per essere una libreria di tag valida, il modulo deve contenere una variabile module-level chiamata <code class=\"docutils literal notranslate\"><span class=\"pre\">register</span></code>, che è una instanza di <code class=\"docutils literal notranslate\"><span class=\"pre\">template.Library</span></code>, nella quale sono registrati tutti i tag ed i filtri. Così, nella parte più alta del tuo modulo, metti quanto segue:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n\n<span class=\"n\">register</span> <span class=\"o\">=</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Library</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Alternativamente, i moduli per i tag di template possono essere registrati attraverso l’argomento <code class=\"docutils literal notranslate\"><span class=\"pre\">'libraries'</span></code> in <a class=\"reference internal\" href=\"/it/4.1/topics/templates/#django.template.backends.django.DjangoTemplates\" title=\"django.template.backends.django.DjangoTemplates\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DjangoTemplates</span></code></a>. Risulta utile quando vuoi usare una label differente rispetto al nome del modulo di tag di template quando carichi i tag di template. Ti permette anche di registrare tag senza installare una applicazione.</p>\n<aside class=\"admonition-behind-the-scenes admonition\">\n<p class=\"admonition-title\">Dietro le quinte</p>\n<p>Per molti più esempi, leggi il codice sorgente dei filtri di default e dei tag di Django. Si trovano rispettivamente in <a class=\"extlink-source reference external\" href=\"https://github.com/django/django/blob/stable/4.1.x/django/template/defaultfilters.py\">django/template/defaultfilters.py</a> e <a class=\"extlink-source reference external\" href=\"https://github.com/django/django/blob/stable/4.1.x/django/template/defaulttags.py\">django/template/defaulttags.py</a>.</p>\n<p>Per avere più informazioni sul tag <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/#std-templatetag-load\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">load</span></code></a>, leggi la sua documentazione.</p>\n</aside>\n</section>\n<section id=\"writing-custom-template-filters\">\n<span id=\"howto-writing-custom-template-filters\"></span><h2>Scrivere filtri template personalizzati<a class=\"heading-anchor\" href=\"#writing-custom-template-filters\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>I filtri custom sono funzioni Python che prendono uno o due argomenti.</p>\n<ul class=\"simple\">\n<li><p>Il valore della variabile (input) - non necessariamente una stringa.</p></li>\n<li><p>Il valore dell’argomento - può avere un valore di default o può essere lasciata fuori.</p></li>\n</ul>\n<p>Per esempio, nel filtro «{{ var|foo:»bar» }}», al filtro foo sarà passata la variabile «var» e l’argomento «bar».</p>\n<p>Dal momento che il linguaggio di template non fornisce la gestione delle eccezioni, ogni eccezione sollevata dal un filtro di template sarà esposta come errore del server. Quindi, le funzioni di filtro dovrebbero evitare di sollevare eccezioni se c’è un valore di fallback ragionevole da restituire. In caso di input che rappresenti un chiaro bug in un template, sollevare una eccezione può ancora essere meglio di un fallimento silente che nasconde il bug.</p>\n<p>Un esempio della definizione di un filtro</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">cut</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"n\">arg</span><span class=\"p\">):</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;Removes all values of arg from the given string&quot;&quot;&quot;</span>\n    <span class=\"k\">return</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"n\">replace</span><span class=\"p\">(</span><span class=\"n\">arg</span><span class=\"p\">,</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>E qui un esempio di come il viene usato</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{{</span> <span class=\"nv\">somevariable</span><span class=\"o\">|</span><span class=\"nf\">cut</span><span class=\"s2\">:&quot;0&quot;</span> <span class=\"cp\">}}</span>\n</code></pre></div>\n<p>Moltri filtri non prendono argomenti. In questo caso, lascia l’argomento fuori dalla tua funzione:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">lower</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">):</span> <span class=\"c1\"># Only one argument.</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;Converts a string into all lowercase&quot;&quot;&quot;</span>\n    <span class=\"k\">return</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span>\n</code></pre></div>\n<section id=\"registering-custom-filters\">\n<h3>Registrazione di filtri personalizzati<a class=\"heading-anchor\" href=\"#registering-custom-filters\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Library.filter\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">django.template.Library.</span></span><span class=\"sig-name descname\"><span class=\"pre\">filter</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Library.filter\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Dopo aver scritto la definizione del filtro, bisogna registrarlo con l’istanza di «Library» al fine di renderlo disponibile per l’uso nel linguaggio dei template di Django.</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"s1\">&#39;cut&#39;</span><span class=\"p\">,</span> <span class=\"n\">cut</span><span class=\"p\">)</span>\n<span class=\"n\">register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"s1\">&#39;lower&#39;</span><span class=\"p\">,</span> <span class=\"n\">lower</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Il metodo «Library.filter()» prende due argomenti:</p>\n<ol class=\"arabic simple\">\n<li><p>Il nome del filtro – una stringa</p></li>\n<li><p>La funzione di compilazione –una funzione Python (non il nome di funzione come stringa).</p></li>\n</ol>\n<p>In alternativa puoi usare <code class=\"docutils literal notranslate\"><span class=\"pre\">register.filter()</span></code> come decorator</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;cut&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">cut</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"n\">arg</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"n\">replace</span><span class=\"p\">(</span><span class=\"n\">arg</span><span class=\"p\">,</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">)</span>\n\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">lower</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Se lasci fuori l’argomento <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code>, come nell’esempio sopra, Django userà il nome della funzione come nome di filtro.</p>\n<p>Infine, <code class=\"docutils literal notranslate\"><span class=\"pre\">register.filter()</span></code> accetta anche tre argomenti keyword, <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">needs_autoescape</span></code> e <code class=\"docutils literal notranslate\"><span class=\"pre\">expects_localtime</span></code>. Questi argomenti sono descritti in <a class=\"reference internal\" href=\"#filters-auto-escaping\"><span class=\"std std-ref\">filtri ed auto-escaping</span></a> e  <a class=\"reference internal\" href=\"#filters-timezones\"><span class=\"std std-ref\">filtri e time zones</span></a> qui sotto.</p>\n</section>\n<section id=\"template-filters-that-expect-strings\">\n<h3>Template filtri che si aspettano delle stringhe<a class=\"heading-anchor\" href=\"#template-filters-that-expect-strings\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.defaultfilters.stringfilter\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">django.template.defaultfilters.</span></span><span class=\"sig-name descname\"><span class=\"pre\">stringfilter</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.defaultfilters.stringfilter\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Se stai scrivendo un filtro di template che si aspetta solo una stringa come primo argomento, dovresti utilizzare il decoratore <code class=\"docutils literal notranslate\"><span class=\"pre\">stringfilter</span></code>. Questo convertirà un oggetto al suo valore stringa prima di passarlo alla tua funzione:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.template.defaultfilters</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">stringfilter</span>\n\n<span class=\"n\">register</span> <span class=\"o\">=</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Library</span><span class=\"p\">()</span>\n\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span>\n<span class=\"nd\">@stringfilter</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">lower</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"n\">lower</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>In questo modo, sarà in grado di passare, diciamo, un intero a questo filtro e non causerà un <code class=\"docutils literal notranslate\"><span class=\"pre\">AttributeError</span></code> (perchè gli integer non hanno metodi <code class=\"docutils literal notranslate\"><span class=\"pre\">lower()</span></code>)</p>\n</section>\n<section id=\"filters-and-auto-escaping\">\n<span id=\"filters-auto-escaping\"></span><h3>Filtri e auto escaping<a class=\"heading-anchor\" href=\"#filters-and-auto-escaping\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Scrivendo un filtro personalizzato, pensa a come il filtro interagirà con i comportamenti di auto-escaping di Django. Nota che nel codice di template possono essere passati due tipi di stringhe:</p>\n<ul>\n<li><p>Le <strong>Raw strings</strong> sono le stringhe native di Python. All’output, sono oggetto di escape se è attivo l’auto-escape o altrimenti presentate senza cambiamenti.</p></li>\n<li><p>Le <strong>Safe strings</strong> sono stringhe che sono state marcate come safe da ulteriori escape a tempo di output. Ogni escaping necessario è già stato fatto. Sono usate comunemente per output che contiene HTML grezzo che deve essere interpretato così come è client-side.</p>\n<p>Internamente, queste stringhe sono di tipo  <a class=\"reference internal\" href=\"/it/4.1/ref/utils/#django.utils.safestring.SafeString\" title=\"django.utils.safestring.SafeString\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SafeString</span></code></a>.  Puoi testarle utilizzando del codice come questo:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils.safestring</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SafeString</span>\n\n<span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"n\">SafeString</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Do something with the &quot;safe&quot; string.</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n</li>\n</ul>\n<p>Il codice dei filtri di template ricade in una delle due situazioni:</p>\n<ol class=\"arabic\">\n<li><p>Il tuo filtro non introduce caratteri HTML non sicuri (<code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">&gt;</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">'</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;</span></code> or <code class=\"docutils literal notranslate\"><span class=\"pre\">&amp;</span></code>) nei risultati che non erano già presenti. In questo caso, puoi lasciare che Django si curi di fare auto-escape per te. Tutto quel che devi fare è impostare <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code> a <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> quando registri la funzione di filtro, così:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">is_safe</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">myfilter</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">value</span>\n</code></pre></div>\n<p>Questo flag dice a Django che se una striga «safe» viene passata nel filtro, il risultato sarà ancora «safe» e se viene passata una stringa «non safe», Django farà automaticamente escape, se necessario.</p>\n<p>Puoi pensarlo come «questo filtro è sicuro – non introduce alcuna possibilità di HTML non safe».</p>\n<p>La ragione per la quale <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code> è necessario è perchè ci sono molte operazioni sulle stringhe che trasformano un oggetto <code class=\"docutils literal notranslate\"><span class=\"pre\">SafeData</span></code> in uno oggetto <code class=\"docutils literal notranslate\"><span class=\"pre\">str</span></code> normale e, piuttosto che cercare di catturarle tutte, cosa che sarebbe molto difficile, Django ripara il danno dopo aver completato il filtro.</p>\n<p>Per esempio, supponi di avere un filtro che aggiunge <code class=\"docutils literal notranslate\"><span class=\"pre\">xx</span></code> alla fine di ogni input. Siccome non introduce caratteri HTML pericolosi al risultato (tranne che nel caso non ci siano già), dovresti marcare il tuo filtro con <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">is_safe</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">add_xx</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"s1\">&#39;</span><span class=\"si\">%s</span><span class=\"s1\">xx&#39;</span> <span class=\"o\">%</span> <span class=\"n\">value</span>\n</code></pre></div>\n<p>Quando questo filtro viene utilizzato in un template quando l’auto-escape è abilitato, Django farà escape dell’output in tutti i casi in cui l’input non sia marcato come «safe».</p>\n<p>Di default, <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code> è <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> e puoi ometterlo da tutti i filtri in cui non sia required.</p>\n<p>Fai attenzione quando decidi se il tuo filtro davvero lascia le stringhe safe come safe. Se stai <em>rimuovendo</em> caratteri, potresti lasciare inavvertitamente tag HTML non bilanciati o entità nei risultati. Per esempio, rimuovere un <code class=\"docutils literal notranslate\"><span class=\"pre\">&gt;</span></code> dall’input potrebbe convertire  <code class=\"docutils literal notranslate\"><span class=\"pre\">1</span></code> in <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;a</span></code>, che avrebbe bisogno di escaping sull’output per evitare problemi. In modo simile, rimuovere un punto e virgola (<code class=\"docutils literal notranslate\"><span class=\"pre\">;</span></code>) può trasformare <code class=\"docutils literal notranslate\"><span class=\"pre\">&amp;amp;</span></code> in <code class=\"docutils literal notranslate\"><span class=\"pre\">&amp;amp</span></code>, che non è più una entità valida e quindi necessità di ulteriore escaping. In molti casi non sarà così complicato ma fai attenzione a problemi come questi quando rivedi il tuo codice.</p>\n<p>Marcare un filtro come <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code> forzerà il valore restituito a stringa. Se il tuo filtro dovrebbe restituire un booleano o altri valori non stringa, marcarlo come <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code> probabilmente avrà conseguenze non volute (come la conversione del booleano False nella stringa “False”).</p>\n</li>\n<li><p>Alternativamente, il tuo codice può occuparsi manualmente di ogni escaping necessario. Questo è necessario quando introduci del nuovo markup HTML nei risultati. Potresti voler marcare l’output come safe così da non introdurre ulteriore escaping ed in questo caso dovrai occuparti da te dell’input.</p>\n<p>Per marcare l’output come stringa safe, usa <a class=\"reference internal\" href=\"/it/4.1/ref/utils/#django.utils.safestring.mark_safe\" title=\"django.utils.safestring.mark_safe\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">django.utils.safestring.mark_safe()</span></code></a>.</p>\n<p>Stai attento però. Devi fare altro oltre a marcare l’output come safe. Devi assicurarti che sia davvero <em>safe</em> e quel che fai dipende dal fatto che l’auto-escaping sia attivo. L’idea è scrivere filtri che possano operare in template in cui l’auto-escape sia attivo o meno per rendere più facili le cose agli autori dei template.</p>\n<p>Perchè il filtro conosca lo stato corrente di auto-escape, imposta il flag <code class=\"docutils literal notranslate\"><span class=\"pre\">needs_autoescape</span></code> a <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> quando registri la tua funzione di filtro (se non lo specifichi, di default è impostato a <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>). Questo flag dice a Django che il tuo filtro vuole che gli sia passato un argomento extra chiamato <code class=\"docutils literal notranslate\"><span class=\"pre\">autoescape</span></code>, che è <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> se l’auto-escape è attivo e <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> altrimenti. Si raccomanda di impostare il default sull’auto-escape a <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, così che chiamando la funzione dal codice Python l’escape sarà abilitato di default.</p>\n<p>Ad esempio, scriviamo un filtro che enfatizza il primo carattere di una stringa:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils.html</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">conditional_escape</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils.safestring</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">mark_safe</span>\n\n<span class=\"n\">register</span> <span class=\"o\">=</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Library</span><span class=\"p\">()</span>\n\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">needs_autoescape</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">initial_letter_filter</span><span class=\"p\">(</span><span class=\"n\">text</span><span class=\"p\">,</span> <span class=\"n\">autoescape</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n    <span class=\"n\">first</span><span class=\"p\">,</span> <span class=\"n\">other</span> <span class=\"o\">=</span> <span class=\"n\">text</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">text</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]</span>\n    <span class=\"k\">if</span> <span class=\"n\">autoescape</span><span class=\"p\">:</span>\n        <span class=\"n\">esc</span> <span class=\"o\">=</span> <span class=\"n\">conditional_escape</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">esc</span> <span class=\"o\">=</span> <span class=\"k\">lambda</span> <span class=\"n\">x</span><span class=\"p\">:</span> <span class=\"n\">x</span>\n    <span class=\"n\">result</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;&lt;strong&gt;</span><span class=\"si\">%s</span><span class=\"s1\">&lt;/strong&gt;</span><span class=\"si\">%s</span><span class=\"s1\">&#39;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"n\">esc</span><span class=\"p\">(</span><span class=\"n\">first</span><span class=\"p\">),</span> <span class=\"n\">esc</span><span class=\"p\">(</span><span class=\"n\">other</span><span class=\"p\">))</span>\n    <span class=\"k\">return</span> <span class=\"n\">mark_safe</span><span class=\"p\">(</span><span class=\"n\">result</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Il flag <code class=\"docutils literal notranslate\"><span class=\"pre\">needs_autoescape</span></code> e l’argomento keyword <code class=\"docutils literal notranslate\"><span class=\"pre\">autoescape</span></code>  fanno sì che la funzione sappia quando l’escaping automatico è attivo nel momento in cui il filtro viene chiamato. Usiamo <code class=\"docutils literal notranslate\"><span class=\"pre\">autoescape</span></code> per decidere quando l’input debba essere passato in <code class=\"docutils literal notranslate\"><span class=\"pre\">django.utils.html.conditional_escape</span></code> o meno. (In quest’ultimo caso, usiamo la funzione identità come funzione di «escape»). La funzione <code class=\"docutils literal notranslate\"><span class=\"pre\">conditional_escape()</span></code> è come <code class=\"docutils literal notranslate\"><span class=\"pre\">escape()</span></code> a parte per il fatto che fa escaping dell’input che <strong>non</strong> è una instanza di <code class=\"docutils literal notranslate\"><span class=\"pre\">SafeData</span></code>. Se una istanza di <code class=\"docutils literal notranslate\"><span class=\"pre\">SafeData</span></code>  viene passata a <code class=\"docutils literal notranslate\"><span class=\"pre\">conditional_escape()</span></code>, i dati vengono restituiti così come sono.</p>\n<p>Infine, nell’esempio sopra, ci ricordiamo di marcare il risultato come safe in modo che il nostro HTML venga inserito direttamente nel template senza ulteriore escaping.</p>\n<p>Non c’è bisogno di preoccuparsi del flag <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code> in questo caso (anche se includerlo non farebbe male). Ogni volta che gestisci manualmente i problemi di auto-escape e restituisci una stringa safe, il flag <code class=\"docutils literal notranslate\"><span class=\"pre\">is_safe</span></code> non cambierebbe comunque niente.</p>\n</li>\n</ol>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avvertimento</p>\n<p>Evitare le vulnerabilità XSS quando si riutilizzano i filtri built-in</p>\n<p>I filtri built-in di Django hanno di default «autoescape=True» al fine di assicurare il corretto autoescaping ed evitare vulnerabilità di tipo cross-site script.</p>\n<p>Nelle vecchie versioni di Django, fai attenzione quando riusi i filtri built-in di Django perchè <code class=\"docutils literal notranslate\"><span class=\"pre\">autoescape</span></code> viene impostato di default a <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>. Dovrai passare <code class=\"docutils literal notranslate\"><span class=\"pre\">autoescape=True</span></code> per fare autoescaping.</p>\n<p>Per esempio, se volessi scrivere un filtro custom chiamato <code class=\"docutils literal notranslate\"><span class=\"pre\">urlize_and_linebreaks</span></code> che combina i filtri <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/#std-templatefilter-urlize\"><code class=\"xref std std-tfilter docutils literal notranslate\"><span class=\"pre\">urlize</span></code></a> e <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/#std-templatefilter-linebreaksbr\"><code class=\"xref std std-tfilter docutils literal notranslate\"><span class=\"pre\">linebreaksbr</span></code></a>, avrebbe questo aspetto:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.template.defaultfilters</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">linebreaksbr</span><span class=\"p\">,</span> <span class=\"n\">urlize</span>\n\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">needs_autoescape</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">urlize_and_linebreaks</span><span class=\"p\">(</span><span class=\"n\">text</span><span class=\"p\">,</span> <span class=\"n\">autoescape</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">linebreaksbr</span><span class=\"p\">(</span>\n        <span class=\"n\">urlize</span><span class=\"p\">(</span><span class=\"n\">text</span><span class=\"p\">,</span> <span class=\"n\">autoescape</span><span class=\"o\">=</span><span class=\"n\">autoescape</span><span class=\"p\">),</span>\n        <span class=\"n\">autoescape</span><span class=\"o\">=</span><span class=\"n\">autoescape</span>\n    <span class=\"p\">)</span>\n</code></pre></div>\n<p>Poi</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{{</span> <span class=\"nv\">comment</span><span class=\"o\">|</span><span class=\"nf\">urlize_and_linebreaks</span> <span class=\"cp\">}}</span>\n</code></pre></div>\n<p>sarebbe equivalente a:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{{</span> <span class=\"nv\">comment</span><span class=\"o\">|</span><span class=\"nf\">urlize</span><span class=\"o\">|</span><span class=\"nf\">linebreaksbr</span> <span class=\"cp\">}}</span>\n</code></pre></div>\n</aside>\n</section>\n<section id=\"filters-and-time-zones\">\n<span id=\"filters-timezones\"></span><h3>Filtri e time zones<a class=\"heading-anchor\" href=\"#filters-and-time-zones\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Se scrivessi un filtro custom che opera sugli oggetti <a class=\"reference external\" href=\"https://docs.python.org/3/library/datetime.html#datetime.datetime\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">datetime</span></code></a>, normalmente lo registreresti con il flag <code class=\"docutils literal notranslate\"><span class=\"pre\">expects_localtime</span></code> a <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">expects_localtime</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">businesshours</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"mi\">9</span> <span class=\"o\">&lt;=</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"n\">hour</span> <span class=\"o\">&lt;</span> <span class=\"mi\">17</span>\n    <span class=\"k\">except</span> <span class=\"ne\">AttributeError</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> <span class=\"s1\">&#39;&#39;</span>\n</code></pre></div>\n<p>Quando questo flag è impostato, se il primo argomento del tuo filtro è un datetime con time zone, Django lo converte alla time zone corrente prima di passarlo al tuo filtro ove appropriato, secondo le <a class=\"reference internal\" href=\"/it/4.1/topics/i18n/timezones/#time-zones-in-templates\"><span class=\"std std-ref\">regole per le conversioni delle time zone nei template</span></a>.</p>\n</section>\n</section>\n<section id=\"writing-custom-template-tags\">\n<span id=\"howto-writing-custom-template-tags\"></span><h2>Scrivere template tag personalizzati<a class=\"heading-anchor\" href=\"#writing-custom-template-tags\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>I tag sono più complessi dei filtri, perchè i tag possono fare qualsiasi cosa. Django offre degli shortcut che rendono la scrittura di molti tipi di tag più semplice. Prima esploreremo questi shortcut, poi spiegheremo come scrivere un tag da zero per quei casi in cui gli shortcut non bastano.</p>\n<section id=\"simple-tags\">\n<span id=\"howto-custom-template-tags-simple-tags\"></span><h3>Semplici tag<a class=\"heading-anchor\" href=\"#simple-tags\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Library.simple_tag\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">django.template.Library.</span></span><span class=\"sig-name descname\"><span class=\"pre\">simple_tag</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Library.simple_tag\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Molti template tag prendono un certo numero di argomenti – stringhe o variabili di template – e restituiscono un risultato dopo aver fatto qualche processamento basato esclusivamente sugli argomenti di input e qualche informazione esterna. Per esempio, un tag <code class=\"docutils literal notranslate\"><span class=\"pre\">current_time</span></code> potrebbe accettare una stringa di formattazione e restituire l’ora come stringa formatta di conseguenza.</p>\n<p>Per facilitare la creazione di questi tipi di tag, Django fornisce una funzione helper, <code class=\"docutils literal notranslate\"><span class=\"pre\">simple_tag</span></code>. Questa funzione, che è un metodo di <code class=\"docutils literal notranslate\"><span class=\"pre\">django.template.Library</span></code>, prende una funzione che accetta un numero arbitrario di argomenti, la racchiude in una funzione <code class=\"docutils literal notranslate\"><span class=\"pre\">render</span></code> e le altre parti necessarie menzionate prima e la registra nel sistema di template.</p>\n<p>La nostra funzione <code class=\"docutils literal notranslate\"><span class=\"pre\">current_time</span></code> dovrebbe essere scritta così:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">datetime</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n\n<span class=\"n\">register</span> <span class=\"o\">=</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Library</span><span class=\"p\">()</span>\n\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">simple_tag</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">current_time</span><span class=\"p\">(</span><span class=\"n\">format_string</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">strftime</span><span class=\"p\">(</span><span class=\"n\">format_string</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Alcune cose da notare a proposito della funzione helper <code class=\"docutils literal notranslate\"><span class=\"pre\">simple_tag</span></code>:</p>\n<ul class=\"simple\">\n<li><p>Controllare il numero richiesto di argomenti ecc…viene già fatto quando la funzione viene chiamata, quindi non dobbiamo farlo.</p></li>\n<li><p>Le virgolette attorno all’argomento (se ce ne sono) sono già state eliminate, quindi riceviamo una stringa semplice.</p></li>\n<li><p>Se l’argomento era una variabile di template, alla nostra funzione viene passato il valore corrente della variabile, non la variabile stessa.</p></li>\n</ul>\n<p>A differenza di altre utilità di tag, <code class=\"docutils literal notranslate\"><span class=\"pre\">simple_tag</span></code> passa il suo output attraverso <a class=\"reference internal\" href=\"/it/4.1/ref/utils/#django.utils.html.conditional_escape\" title=\"django.utils.html.conditional_escape\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">conditional_escape()</span></code></a> se il template context è in modalità autoescape, per assicurare un HTML corretto e proteggerti da vulnerabilità XSS.</p>\n<p>Se non si desidera un escaping aggiuntivo, sarà necessario utilizzare <a class=\"reference internal\" href=\"/it/4.1/ref/utils/#django.utils.safestring.mark_safe\" title=\"django.utils.safestring.mark_safe\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">mark_safe()</span></code></a> solo se si è assolutamente sicuri che il codice non contenga vulnerabilità XSS. Per creare piccoli frammenti di codice HTML, è fortemente raccomandato l’uso di <a class=\"reference internal\" href=\"/it/4.1/ref/utils/#django.utils.html.format_html\" title=\"django.utils.html.format_html\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">format_html()</span></code></a> invece di <code class=\"docutils literal notranslate\"><span class=\"pre\">mark_safe()</span></code>.</p>\n<p>Se il tuo tag nel template ha bisogno di accedere al context corrente, puoi usare l’argomento <code class=\"docutils literal notranslate\"><span class=\"pre\">takes_context</span></code> quando registri il tuo tag:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">simple_tag</span><span class=\"p\">(</span><span class=\"n\">takes_context</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">current_time</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">,</span> <span class=\"n\">format_string</span><span class=\"p\">):</span>\n    <span class=\"n\">timezone</span> <span class=\"o\">=</span> <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s1\">&#39;timezone&#39;</span><span class=\"p\">]</span>\n    <span class=\"k\">return</span> <span class=\"n\">your_get_current_time_method</span><span class=\"p\">(</span><span class=\"n\">timezone</span><span class=\"p\">,</span> <span class=\"n\">format_string</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Nota che il primo argomento deve chiamarsi «context»</p>\n<p>Per ulteriori informazioni su come funziona l’opzione <code class=\"docutils literal notranslate\"><span class=\"pre\">takes_context</span></code> vedere la sezione su <a class=\"reference internal\" href=\"#howto-custom-template-tags-inclusion-tags\"><span class=\"std std-ref\">inclusion tags</span></a>.</p>\n<p>Se hai bisogno dirinominare il tag, puoi fornirne un nome personalizzato:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">register</span><span class=\"o\">.</span><span class=\"n\">simple_tag</span><span class=\"p\">(</span><span class=\"k\">lambda</span> <span class=\"n\">x</span><span class=\"p\">:</span> <span class=\"n\">x</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;minusone&#39;</span><span class=\"p\">)</span>\n\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">simple_tag</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s1\">&#39;minustwo&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">some_function</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">value</span> <span class=\"o\">-</span> <span class=\"mi\">2</span>\n</code></pre></div>\n<p>Le funzioni <code class=\"docutils literal notranslate\"><span class=\"pre\">simple_tag</span></code> possono accettare un numero qualsiasi di argomenti posizionali o di parole chiave. Per esempio:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">simple_tag</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_tag</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"n\">warning</span> <span class=\"o\">=</span> <span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s1\">&#39;warning&#39;</span><span class=\"p\">]</span>\n    <span class=\"n\">profile</span> <span class=\"o\">=</span> <span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s1\">&#39;profile&#39;</span><span class=\"p\">]</span>\n    <span class=\"o\">...</span>\n    <span class=\"k\">return</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>Quindi nel template qualsiasi argomento, separato da spazi, può essere passato al tag del template. Come in Python, i valori per gli argomenti delle parole chiave sono impostati usando il segno di uguale (»<code class=\"docutils literal notranslate\"><span class=\"pre\">=</span></code>») e devono essere inseriti dopo gli argomenti posizionali. Per esempio:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">my_tag</span> <span class=\"m\">123</span> <span class=\"s2\">&quot;abcd&quot;</span> <span class=\"nv\">book.title</span> <span class=\"nv\">warning</span><span class=\"o\">=</span><span class=\"nv\">message</span><span class=\"o\">|</span><span class=\"nf\">lower</span> <span class=\"nv\">profile</span><span class=\"o\">=</span><span class=\"nv\">user.profile</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>È possibile memorizzare i risultati del tag in una variabile del template anziché esporlo direttamente. Questo viene fatto usando l’argomento <code class=\"docutils literal notranslate\"><span class=\"pre\">as</span></code> seguito dal nome della variabile. In questo modo puoi mostrare il contenuto dove ritieni opportuno:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">current_time</span> <span class=\"s2\">&quot;%Y-%m-%d %I:%M %p&quot;</span> <span class=\"k\">as</span> <span class=\"nv\">the_time</span> <span class=\"cp\">%}</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>The time is <span class=\"cp\">{{</span> <span class=\"nv\">the_time</span> <span class=\"cp\">}}</span>.<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n</section>\n<section id=\"inclusion-tags\">\n<span id=\"howto-custom-template-tags-inclusion-tags\"></span><h3>Tag di inclusione<a class=\"heading-anchor\" href=\"#inclusion-tags\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.template.Library.inclusion_tag\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">django.template.Library.</span></span><span class=\"sig-name descname\"><span class=\"pre\">inclusion_tag</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.template.Library.inclusion_tag\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Un altro tipo comune di tag template è il tipo che visualizza alcuni dati eseguendo il rendering di <em>un altro</em> template. Ad esempio, l’interfaccia di amministrazione di Django utilizza tag template personalizzati per visualizzare i pulsanti «aggiungi/modifica» nella parte inferiore delle pagine modulo (form). Quei pulsanti hanno sempre lo stesso aspetto, ma le destinazioni del collegamento cambiano a seconda dell’oggetto che viene modificato, quindi sono un caso perfetto per l’utilizzo di un piccolo template pieno di dettagli dall’oggetto corrente. (Nel caso dell’amministratore, questo è il tag <code class=\"docutils literal notranslate\"><span class=\"pre\">submit_row</span></code>.)</p>\n<p>I tag di questo tipo sono detti «tag di inclusione»</p>\n<p>La scrittura di tag di inclusione è probabilmente meglio dimostrata dall’esempio. Scriviamo un tag che produca un elenco di scelte per un dato oggetto <code class=\"docutils literal notranslate\"><span class=\"pre\">Poll</span></code>, come è stato creato in <a class=\"reference internal\" href=\"/it/4.1/intro/tutorial02/#creating-models\"><span class=\"std std-ref\">tutorials</span></a>. Useremo il tag in questo modo:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">show_results</span> <span class=\"nv\">poll</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>… e l’output sarà qualcosa di simile a questo:</p>\n<div class=\"code-block\" data-language=\"html\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Html</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Html code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>First choice<span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>Second choice<span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>Third choice<span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>Innanzitutto, definisci la funzione che accetta l’argomento e produce un dizionario di dati per il risultato. Il punto importante qui è che dobbiamo solo restituire un dizionario, non qualcosa di più complesso. Questo verrà utilizzato come context del template per il frammento del template. Esempio:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">show_results</span><span class=\"p\">(</span><span class=\"n\">poll</span><span class=\"p\">):</span>\n    <span class=\"n\">choices</span> <span class=\"o\">=</span> <span class=\"n\">poll</span><span class=\"o\">.</span><span class=\"n\">choice_set</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n    <span class=\"k\">return</span> <span class=\"p\">{</span><span class=\"s1\">&#39;choices&#39;</span><span class=\"p\">:</span> <span class=\"n\">choices</span><span class=\"p\">}</span>\n</code></pre></div>\n<p>Quindi, crea il template utilizzato per eseguire il rendering dell’output dei tag. Questo modello è una caratteristica fissa dei tag: lo specifica l’autore del tag, non il designer del template. Seguendo il nostro esempio, il template è molto breve:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">choice</span> <span class=\"k\">in</span> <span class=\"nv\">choices</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span> <span class=\"cp\">{{</span> <span class=\"nv\">choice</span> <span class=\"cp\">}}</span> <span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>Ora, crea e registra il tag di inclusione chiamando il metodo <code class=\"docutils literal notranslate\"><span class=\"pre\">inclusion_tag()</span></code> su un oggetto <code class=\"docutils literal notranslate\"><span class=\"pre\">Library</span></code>. Seguendo il nostro esempio, se il template sopra si trova in un file chiamato <code class=\"docutils literal notranslate\"><span class=\"pre\">results.html</span></code> in una directory che viene cercata dall’invocatore del template, registreremo il tag in questo modo:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># Here, register is a django.template.Library instance, as before</span>\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">inclusion_tag</span><span class=\"p\">(</span><span class=\"s1\">&#39;results.html&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">show_results</span><span class=\"p\">(</span><span class=\"n\">poll</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>In alternativa è possibile registrare il tag di inclusione utilizzando un’istanza di <a class=\"reference internal\" href=\"/it/4.1/ref/templates/api/#django.template.Template\" title=\"django.template.Template\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.template.Template</span></code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.template.loader</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">get_template</span>\n<span class=\"n\">t</span> <span class=\"o\">=</span> <span class=\"n\">get_template</span><span class=\"p\">(</span><span class=\"s1\">&#39;results.html&#39;</span><span class=\"p\">)</span>\n<span class=\"n\">register</span><span class=\"o\">.</span><span class=\"n\">inclusion_tag</span><span class=\"p\">(</span><span class=\"n\">t</span><span class=\"p\">)(</span><span class=\"n\">show_results</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>…alla prima creazione della funzione.</p>\n<p>A volte, i tag di inclusione potrebbero richiedere un numero elevato di argomenti, rendendo difficile per gli autori dei template passare tutti gli argomenti e ricordare il loro ordine. Per risolvere questo problema, Django fornisce un’opzione <code class=\"docutils literal notranslate\"><span class=\"pre\">takes_context</span></code> per i tag di inclusione. Se specifichi <code class=\"docutils literal notranslate\"><span class=\"pre\">takes_context</span></code> nella creazione di un tag nel template, il tag non avrà argomenti richiesti e la funzione Python sottostante avrà un argomento – il context del template a partire da quando il tag è stato chiamato.</p>\n<p>Ad esempio, supponiamo che tu stia scrivendo un tag di inclusione che sarà sempre utilizzato in un context che contiene variabili <code class=\"docutils literal notranslate\"><span class=\"pre\">home_link</span></code> e <code class=\"docutils literal notranslate\"><span class=\"pre\">home_title</span></code> che puntano alla pagina principale. Ecco come sarebbe la funzione Python:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">inclusion_tag</span><span class=\"p\">(</span><span class=\"s1\">&#39;link.html&#39;</span><span class=\"p\">,</span> <span class=\"n\">takes_context</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">jump_link</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"p\">{</span>\n        <span class=\"s1\">&#39;link&#39;</span><span class=\"p\">:</span> <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s1\">&#39;home_link&#39;</span><span class=\"p\">],</span>\n        <span class=\"s1\">&#39;title&#39;</span><span class=\"p\">:</span> <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s1\">&#39;home_title&#39;</span><span class=\"p\">],</span>\n    <span class=\"p\">}</span>\n</code></pre></div>\n<p>Si noti che il primo parametro della funzione <em>deve</em> essere chiamato <code class=\"docutils literal notranslate\"><span class=\"pre\">context</span></code>.</p>\n<p>In quella riga <code class=\"docutils literal notranslate\"><span class=\"pre\">register.inclusion_tag()</span></code>, abbiamo specificato <code class=\"docutils literal notranslate\"><span class=\"pre\">takes_context=True</span></code> e il nome del template. Ecco come potrebbe apparire il template <code class=\"docutils literal notranslate\"><span class=\"pre\">link.html</span></code>:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code>Jump directly to <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{{</span> <span class=\"nv\">link</span> <span class=\"cp\">}}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">title</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>.\n</code></pre></div>\n<p>Quindi, ogni volta che desideri utilizzare quel tag personalizzato, carica la sua libreria e chiamala senza argomenti, in questo modo:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">jump_link</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Nota che quando usi <code class=\"docutils literal notranslate\"><span class=\"pre\">takes_context=True</span></code>, non è necessario passare argomenti al tag del modello. Ottiene automaticamente l’accesso al context.</p>\n<p>Il parametro <code class=\"docutils literal notranslate\"><span class=\"pre\">takes_context</span></code> è predefinito su <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>. Quando è impostato su <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, al tag viene passato l’oggetto context, come in questo esempio. Questa è l’unica differenza tra questo caso e il precedente esempio di <code class=\"docutils literal notranslate\"><span class=\"pre\">inclusion_tag</span></code>.</p>\n<p>Le funzioni <code class=\"docutils literal notranslate\"><span class=\"pre\">inclusion_tag</span></code> possono accettare qualsiasi argomento posizionale o di parole chiave. Per esempio:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">inclusion_tag</span><span class=\"p\">(</span><span class=\"s1\">&#39;my_template.html&#39;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_tag</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"n\">warning</span> <span class=\"o\">=</span> <span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s1\">&#39;warning&#39;</span><span class=\"p\">]</span>\n    <span class=\"n\">profile</span> <span class=\"o\">=</span> <span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s1\">&#39;profile&#39;</span><span class=\"p\">]</span>\n    <span class=\"o\">...</span>\n    <span class=\"k\">return</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>Quindi nel template qualsiasi argomento, separato da spazi, può essere passato al tag del template. Come in Python, i valori per gli argomenti delle parole chiave sono impostati usando il segno di uguale (»<code class=\"docutils literal notranslate\"><span class=\"pre\">=</span></code>») e devono essere inseriti dopo gli argomenti posizionali. Per esempio:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">my_tag</span> <span class=\"m\">123</span> <span class=\"s2\">&quot;abcd&quot;</span> <span class=\"nv\">book.title</span> <span class=\"nv\">warning</span><span class=\"o\">=</span><span class=\"nv\">message</span><span class=\"o\">|</span><span class=\"nf\">lower</span> <span class=\"nv\">profile</span><span class=\"o\">=</span><span class=\"nv\">user.profile</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n</section>\n<section id=\"advanced-custom-template-tags\">\n<h3>Tag di template personalizzati avanzati<a class=\"heading-anchor\" href=\"#advanced-custom-template-tags\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>A volte le funzionalità di base per la creazione di tag in template personalizzati non sono sufficienti. Non preoccuparti, Django ti dà accesso completo al necessario per creare un tag template da zero.</p>\n</section>\n<section id=\"a-quick-overview\">\n<h3>Una rapida panoramica<a class=\"heading-anchor\" href=\"#a-quick-overview\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Il sistema di template funziona in un processo in due fasi: compilazione e rendering. Per definire un tag template personalizzato, specifica come funziona la compilation e come funziona il rendering.</p>\n<p>Quando Django compila un template, divide il testo del template grezzo in “”nodi””. Ogni nodo è un’istanza di <code class=\"docutils literal notranslate\"><span class=\"pre\">django.template.Node</span></code> e ha un metodo <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code>. Un template compilato è un elenco di oggetti <code class=\"docutils literal notranslate\"><span class=\"pre\">Nodo</span></code>. Quando chiami <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> su un oggetto del template compilato, il template chiama <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> su ogni <code class=\"docutils literal notranslate\"><span class=\"pre\">Nodo</span></code> nella sua lista dei nodi, con il context fornito. I risultati sono tutti concatenati insieme per formare il risultato (output) del template.</p>\n<p>Quindi, per definire un custom template tag: specifica come il template tag grezzo viene convertito in un <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> (usa la funzione di compilazione) e definisci cosa fa il metodo <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> del nodo.</p>\n</section>\n<section id=\"writing-the-compilation-function\">\n<h3>Scrivere la funzione di compilazione<a class=\"heading-anchor\" href=\"#writing-the-compilation-function\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Per ogni tag del template che incontra il parser del template, chiama una funzione Python con il contenuto del tag e l’oggetto del parser stesso. Questa funzione è responsabile della restituzione di un’istanza <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> basata sul contenuto del template tag.</p>\n<p>Per esempio, scriviamo un’implementazione completa del nostro tag template, <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">current_time</span> <span class=\"pre\">%}</span></code>, che mostra la data/ora corrente, formattata secondo un parametro dato nel tag, sintassi :func:<a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>~time.strftime ` . È una buona idea decidere la sintassi dei template tag prima di ogni altra cosa. Nel nostro caso, supponiamo che il tag debba essere utilizzato in questo modo:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>The time is <span class=\"cp\">{%</span> <span class=\"k\">current_time</span> <span class=\"s2\">&quot;%Y-%m-%d %I:%M %p&quot;</span> <span class=\"cp\">%}</span>.<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>Il parser per questa funzione dovrebbe prendere il parametro e creare un oggetto <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">do_current_time</span><span class=\"p\">(</span><span class=\"n\">parser</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"c1\"># split_contents() knows not to split quoted strings.</span>\n        <span class=\"n\">tag_name</span><span class=\"p\">,</span> <span class=\"n\">format_string</span> <span class=\"o\">=</span> <span class=\"n\">token</span><span class=\"o\">.</span><span class=\"n\">split_contents</span><span class=\"p\">()</span>\n    <span class=\"k\">except</span> <span class=\"ne\">ValueError</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">TemplateSyntaxError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;</span><span class=\"si\">%r</span><span class=\"s2\"> tag requires a single argument&quot;</span> <span class=\"o\">%</span> <span class=\"n\">token</span><span class=\"o\">.</span><span class=\"n\">contents</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">()[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n        <span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"p\">(</span><span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"ow\">and</span> <span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"ow\">in</span> <span class=\"p\">(</span><span class=\"s1\">&#39;&quot;&#39;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;&#39;&quot;</span><span class=\"p\">)):</span>\n        <span class=\"k\">raise</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">TemplateSyntaxError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;</span><span class=\"si\">%r</span><span class=\"s2\"> tag&#39;s argument should be in quotes&quot;</span> <span class=\"o\">%</span> <span class=\"n\">tag_name</span>\n        <span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">CurrentTimeNode</span><span class=\"p\">(</span><span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n</code></pre></div>\n<p>Note:</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">parser</span></code> è l’oggetto parser di template. Non ne abbiamo bisogno in questo esempio.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">token.contents</span></code> è una stringa di contenuti grezzi del tag. Nel nostro esempio, è <code class=\"docutils literal notranslate\"><span class=\"pre\">'current_time</span> <span class=\"pre\">&quot;%Y-%m-%d</span> <span class=\"pre\">%I:%M</span> <span class=\"pre\">%p&quot;'</span></code>.</p></li>\n<li><p>Il metodo <code class=\"docutils literal notranslate\"><span class=\"pre\">token.split_contents()</span></code> separa gli argomenti con gli spazi tenendo assieme le stringhe tra virgolette. Il più diretto <code class=\"docutils literal notranslate\"><span class=\"pre\">token.contents.split()</span></code> non sarebbe così robusto, perchè dividerebbe pedissequamente <em>tutti</em> gli spazi, inclusi quelli tra virgolette. E” una buona idea usare sempre token.split_contents()`.</p></li>\n<li><p>Questa funzione è responsabile di sollevare <code class=\"docutils literal notranslate\"><span class=\"pre\">django.template.TemplateSyntaxError</span></code>, con messaggi utili, per ogni errore di sintassi.</p></li>\n<li><p>Le eccezioni <code class=\"docutils literal notranslate\"><span class=\"pre\">TemplateSyntaxError</span></code> usano la variabile <code class=\"docutils literal notranslate\"><span class=\"pre\">tag_name</span></code>. Non fare hard-coding del nome del tag nei tuoi messaggi di errore, perchè questo accoppia il nome del tuo tag alla funzione. <code class=\"docutils literal notranslate\"><span class=\"pre\">token.contents.split()[0]</span></code> sarò «sempre» il nome del tuo tag – anche quando il tag non prende argomenti.</p></li>\n<li><p>La funzione restituisce un <code class=\"docutils literal notranslate\"><span class=\"pre\">CurrentTimeNode</span></code> con tutto ciò di cui il nodo ha bisogno di sapere circa questo tag. In questo caso, passa l’argomento –<code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;%Y-%m-%d</span> <span class=\"pre\">%I:%M</span> <span class=\"pre\">%p&quot;</span></code>. Le virgolette in testa ed in coda dal tag di template sono rimosse in <code class=\"docutils literal notranslate\"><span class=\"pre\">format_string[1:-1]</span></code>.</p></li>\n<li><p>Il parsing è molto di basso livello. Gli sviluppatori di Django hanno sperimentato nello scrivere piccoli framework su questo sistema di parsing, usando tecniche con le grammatiche EBNF, ma questi esperimenti hanno reso il motore di template troppo lento. E” di basso livello perchè in questo modo è più veloce.</p></li>\n</ul>\n</section>\n<section id=\"writing-the-renderer\">\n<h3>Scrivere il renderer<a class=\"heading-anchor\" href=\"#writing-the-renderer\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Il secondo passo nello scrivere tag personalizzati è definire una sottoclasse <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> che ha un metodo <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code>.</p>\n<p>Continuando l’esempio precedente, dobbiamo definire <code class=\"docutils literal notranslate\"><span class=\"pre\">CurrentTimeNode</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">datetime</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CurrentTimeNode</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">format_string</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span> <span class=\"o\">=</span> <span class=\"n\">format_string</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">strftime</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Note:</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code> prende <code class=\"docutils literal notranslate\"><span class=\"pre\">format_string</span></code> da <code class=\"docutils literal notranslate\"><span class=\"pre\">do_current_time()</span></code>. Passa sempre qualsiasi opzione/parametro/argomento ad un <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> tramite il suo <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code>.</p></li>\n<li><p>Il metodo <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> è dove viene fatto il lavoro vero e proprio.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> generalmente dovrebbe fallire in modo silenzioso, in particolare in un ambiente di produzione. In qualche caso tuttavia, specialmente se <code class=\"docutils literal notranslate\"><span class=\"pre\">context.template.engine.debug</span></code> è impostato a <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, questo metodo può sollevare una eccezione per facilitare il debugging. Per esempio, molti tag core sollevano <code class=\"docutils literal notranslate\"><span class=\"pre\">django.template.TemplateSyntaxError</span></code> se ricevono un numero di argomenti sbagliato.</p></li>\n</ul>\n<p>In ultimo, questo disaccoppiamento tra compilazione e rendering ha come risultato un sistema di template efficiente, perchè un template può fare render di diversi contesti senza dover essere analizzato più volte.</p>\n</section>\n<section id=\"auto-escaping-considerations\">\n<span id=\"tags-auto-escaping\"></span><h3>Considerazioni sull’auto-escape<a class=\"heading-anchor\" href=\"#auto-escaping-considerations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>L’output da template tag <strong>non è</strong> automaticamente passato ai filtri di auto-escape (con l’eccezione di <a class=\"reference internal\" href=\"#django.template.Library.simple_tag\" title=\"django.template.Library.simple_tag\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">simple_tag()</span></code></a> come descritto sopra). Comunque, ci sono ancora un paio di cose che dovresti tenere a mente quando scrivi un tag di template.</p>\n<p>Se il metodo <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> del tuo template tag immagazzina il risultato in una variabile di contesto (piuttosto che restituirlo in una stringa), dovrebbe fare attenzione a chiamare <code class=\"docutils literal notranslate\"><span class=\"pre\">mark_safe()</span></code> quando è opportuno. Quando la variabile viene resa, alla fine, in quel momento sarà influenzata dalle impostazioni di auto-escape, così il contenuto che dovrebbe essere sicuro rispetto ad un ulteriore escaping dovrebbe essere marcato come tale.</p>\n<p>Inoltre, se il tuo tag di template crea un nuovo contesto per fare qualche sotto-rendering, imposta l’attributo di auto-escape al valore corrente di contesto. Il metodo <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__</span></code> per la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Context</span></code> prende un parametro chiamato <code class=\"docutils literal notranslate\"><span class=\"pre\">autoescape</span></code> che puoi usare per questo scopo. Per esempio:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.template</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Context</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"n\">new_context</span> <span class=\"o\">=</span> <span class=\"n\">Context</span><span class=\"p\">({</span><span class=\"s1\">&#39;var&#39;</span><span class=\"p\">:</span> <span class=\"n\">obj</span><span class=\"p\">},</span> <span class=\"n\">autoescape</span><span class=\"o\">=</span><span class=\"n\">context</span><span class=\"o\">.</span><span class=\"n\">autoescape</span><span class=\"p\">)</span>\n    <span class=\"c1\"># ... Do something with new_context ...</span>\n</code></pre></div>\n<p>Non è una situazione molto comune, ma è utile se si fa rendering di un template da soli. Per esempio:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n    <span class=\"n\">t</span> <span class=\"o\">=</span> <span class=\"n\">context</span><span class=\"o\">.</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">engine</span><span class=\"o\">.</span><span class=\"n\">get_template</span><span class=\"p\">(</span><span class=\"s1\">&#39;small_fragment.html&#39;</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">t</span><span class=\"o\">.</span><span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">Context</span><span class=\"p\">({</span><span class=\"s1\">&#39;var&#39;</span><span class=\"p\">:</span> <span class=\"n\">obj</span><span class=\"p\">},</span> <span class=\"n\">autoescape</span><span class=\"o\">=</span><span class=\"n\">context</span><span class=\"o\">.</span><span class=\"n\">autoescape</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>Se non ci fossimo curati di passare il valore <code class=\"docutils literal notranslate\"><span class=\"pre\">context.autoescape</span></code> al nostro nuovo <code class=\"docutils literal notranslate\"><span class=\"pre\">Context</span></code> in questo esempio, sui risultati sarebbe <em>sempre</em> stato fatto automaticamente escape, il che avrebbe potuto non essere il comportamento desiderato se il tag di template fosse stato usato in un blocco <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/#std-templatetag-autoescape\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">autoescape</span> <span class=\"pre\">off</span> <span class=\"pre\">%}</span></code></a></p>\n</section>\n<section id=\"thread-safety-considerations\">\n<span id=\"template-tag-thread-safety\"></span><h3>Considerazioni sulla sicurezza<a class=\"heading-anchor\" href=\"#thread-safety-considerations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Una volta che un nodo viene analizzato, il suo metodo <code class=\"docutils literal notranslate\"><span class=\"pre\">render</span></code> può essere chiamato un numero indefinito di volte. Dal momento che Django ogni tanto gira in ambienti multi-threaded, un singolo nodo può essere simultaneamente reso con differenti contesti in risposta a richieste differenti. Quindi, è importante assicurarsi che i propri template tag siano thread safe.</p>\n<p>Per essere sicuro che i template tag siano thread safe, non dovresti mai immagazzinare informazioni di stato sul nodo stesso. Per esempio, Django offre un template tag builtin <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/#std-templatetag-cycle\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">cycle</span></code></a> che compie un ciclo lungo una lista di date stringhe ogni volta che viene visualizzato:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">o</span> <span class=\"k\">in</span> <span class=\"nv\">some_list</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">tr</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{%</span> <span class=\"k\">cycle</span> <span class=\"s1\">&#39;row1&#39;</span> <span class=\"s1\">&#39;row2&#39;</span> <span class=\"cp\">%}</span><span class=\"s\">&quot;</span><span class=\"p\">&gt;</span>\n        ...\n    <span class=\"p\">&lt;/</span><span class=\"nt\">tr</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Una implementazione naive di <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode</span></code> può avere un aspetto simile:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">itertools</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CycleNode</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">cyclevars</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cycle_iter</span> <span class=\"o\">=</span> <span class=\"n\">itertools</span><span class=\"o\">.</span><span class=\"n\">cycle</span><span class=\"p\">(</span><span class=\"n\">cyclevars</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"nb\">next</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cycle_iter</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Ma, supponiamo di avere due template che visualizzano lo snippet di template qui sopra allo stesso tempo:</p>\n<ol class=\"arabic simple\">\n<li><p>Il thread 1 esegue la sua prima iterazione di loop, <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode.render()</span></code> restituisce “row1”</p></li>\n<li><p>Il thread 2 esegue la sua prima iterazione di loop, <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode.render()</span></code> restituisce “row2”</p></li>\n<li><p>Il thread 1 esegue la sua seconda iterazione di loop, <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode.render()</span></code> restituisce “row1”</p></li>\n<li><p>Il thread 2 esegue la sua seconda iterazione di loop, <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode.render()</span></code> restituisce “row2”</p></li>\n</ol>\n<p>CycleNode sta iterando, ma sta iterando globalmente. Per quel che ne sanno Thread 1 e Thread 2, sta restituendo sempre lo stesso valore. Non è quello che vogliamo!</p>\n<p>Per risolvere questo problema, Django offre un <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context</span></code> che è associato con il <code class=\"docutils literal notranslate\"><span class=\"pre\">context</span></code> del template che si mostra in quel momento. <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context</span></code> si comporta come un dizionario Python e dovrebbe essere usato per memorizzare lo stato di <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> tra le invocazioni del metodo <code class=\"docutils literal notranslate\"><span class=\"pre\">render</span></code>.</p>\n<p>Rifattorizziamo la nostra implementazione di <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode</span></code> per usare <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CycleNode</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">cyclevars</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cyclevars</span> <span class=\"o\">=</span> <span class=\"n\">cyclevars</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">context</span><span class=\"o\">.</span><span class=\"n\">render_context</span><span class=\"p\">:</span>\n            <span class=\"n\">context</span><span class=\"o\">.</span><span class=\"n\">render_context</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">itertools</span><span class=\"o\">.</span><span class=\"n\">cycle</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cyclevars</span><span class=\"p\">)</span>\n        <span class=\"n\">cycle_iter</span> <span class=\"o\">=</span> <span class=\"n\">context</span><span class=\"o\">.</span><span class=\"n\">render_context</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"p\">]</span>\n        <span class=\"k\">return</span> <span class=\"nb\">next</span><span class=\"p\">(</span><span class=\"n\">cycle_iter</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Nota che è perfettamente sicuro memorizzare l’informazione globale che non cambierà attraverso il ciclo di vita del <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> come attributo. Nel caso di <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode</span></code>, l’argomento <code class=\"docutils literal notranslate\"><span class=\"pre\">cyclevars</span></code> non cambia dopo che <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code>  viene istanziato, quindi non abbiamo bisogno di metterlo in <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context</span></code>. Ma l’informazione di stato che è specifica del template che si sta presentando, come l’iterazione corrente di  <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode</span></code>, dovrebbe essere memorizzata in <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context</span></code>.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Nota</p>\n<p>Nota come abbiamo usato <code class=\"docutils literal notranslate\"><span class=\"pre\">self</span></code> per dare uno scope alla specifica informazione <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNode</span></code> nel <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context</span></code>. Ci possono essere molteplici <code class=\"docutils literal notranslate\"><span class=\"pre\">CycleNodes</span></code> in un dato template, quindi abbiamo bisogno di stare attenti a non andare in conflitto con l’informazione di stato di un altro nodo. Il modo più semplice di farlo è usare sempre <code class=\"docutils literal notranslate\"><span class=\"pre\">self</span></code> come chiave in <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context</span></code>. Se stai tenendo traccia di diverse variabili di stato, rendi <code class=\"docutils literal notranslate\"><span class=\"pre\">render_context[self]</span></code> un dizionario.</p>\n</aside>\n</section>\n<section id=\"registering-the-tag\">\n<h3>Registrare il tag<a class=\"heading-anchor\" href=\"#registering-the-tag\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Infine, registra il tag nell’istanza del tuo modulo <code class=\"docutils literal notranslate\"><span class=\"pre\">Library</span></code>, come spiegato in  <span class=\"xref std std-ref\">scrivere tag di template personalizzati</span> qui sopra. Per esempio:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">register</span><span class=\"o\">.</span><span class=\"n\">tag</span><span class=\"p\">(</span><span class=\"s1\">&#39;current_time&#39;</span><span class=\"p\">,</span> <span class=\"n\">do_current_time</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Il methodo <code class=\"docutils literal notranslate\"><span class=\"pre\">tag()</span></code> ha bisogni di due argomenti:</p>\n<ol class=\"arabic simple\">\n<li><p>Il nome del template tag – una stringa. Se viene tralasciato, il nome della fu..?</p></li>\n<li><p>La funzione di compilazione –una funzione Python (non il nome di funzione come stringa).</p></li>\n</ol>\n<p>Così come con la registrazione di un filtro, è anche possibile usarlo come decoratore:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">tag</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;current_time&quot;</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">do_current_time</span><span class=\"p\">(</span><span class=\"n\">parser</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n<span class=\"nd\">@register</span><span class=\"o\">.</span><span class=\"n\">tag</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">shout</span><span class=\"p\">(</span><span class=\"n\">parser</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Se non specifichi l’argomento <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code>, come nel secondo esempio qui sopra, Django userà il nome della funzione come nome del tag.</p>\n</section>\n<section id=\"passing-template-variables-to-the-tag\">\n<h3>Passare variabili del template ai tag<a class=\"heading-anchor\" href=\"#passing-template-variables-to-the-tag\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Anche se puoi passare un numero arbitrario di argomenti ad un tag di template usando <code class=\"docutils literal notranslate\"><span class=\"pre\">token.split_contents()</span></code>, gli argomenti sono tutti spacchettati come string literals. E” richiesto un po” più di lavoro per passare un contenuto dinamico (una variabile di template) come argomento ad un tag di template.</p>\n<p>Mentre gli esempi precedenti hanno formattato l’ora corrente in una stringa e restituito una stringa, supponi di voler passare un <a class=\"reference internal\" href=\"/it/4.1/ref/models/fields/#django.db.models.DateTimeField\" title=\"django.db.models.DateTimeField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DateTimeField</span></code></a> da un oggetto ed avere il template tag che formatta il date-time:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>This post was last updated at <span class=\"cp\">{%</span> <span class=\"k\">format_time</span> <span class=\"nv\">blog_entry.date_updated</span> <span class=\"s2\">&quot;%Y-%m-%d %I:%M %p&quot;</span> <span class=\"cp\">%}</span>.<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>All’inizio, <code class=\"docutils literal notranslate\"><span class=\"pre\">token.split_contents()</span></code> restituirà tre valori:</p>\n<ol class=\"arabic simple\">\n<li><p>Il nome tag <code class=\"docutils literal notranslate\"><span class=\"pre\">format_time</span></code>.</p></li>\n<li><p>La stringa <code class=\"docutils literal notranslate\"><span class=\"pre\">'blog_entry.date_updated'</span></code> (senza le virgolette).</p></li>\n<li><p>La stringa di formattazione <code class=\"docutils literal notranslate\"><span class=\"pre\">'&quot;%Y-%m-%d</span> <span class=\"pre\">%I:%M</span> <span class=\"pre\">%p&quot;'</span></code>. Il valore restituito da <code class=\"docutils literal notranslate\"><span class=\"pre\">split_contents()</span></code> includerà le virgolette in capo ed in coda agli string literals come questo.</p></li>\n</ol>\n<p>Adesso il tuo tag comincia a sembrare così:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">do_format_time</span><span class=\"p\">(</span><span class=\"n\">parser</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"c1\"># split_contents() knows not to split quoted strings.</span>\n        <span class=\"n\">tag_name</span><span class=\"p\">,</span> <span class=\"n\">date_to_be_formatted</span><span class=\"p\">,</span> <span class=\"n\">format_string</span> <span class=\"o\">=</span> <span class=\"n\">token</span><span class=\"o\">.</span><span class=\"n\">split_contents</span><span class=\"p\">()</span>\n    <span class=\"k\">except</span> <span class=\"ne\">ValueError</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">TemplateSyntaxError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;</span><span class=\"si\">%r</span><span class=\"s2\"> tag requires exactly two arguments&quot;</span> <span class=\"o\">%</span> <span class=\"n\">token</span><span class=\"o\">.</span><span class=\"n\">contents</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">()[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n        <span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"p\">(</span><span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"ow\">and</span> <span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"ow\">in</span> <span class=\"p\">(</span><span class=\"s1\">&#39;&quot;&#39;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;&#39;&quot;</span><span class=\"p\">)):</span>\n        <span class=\"k\">raise</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">TemplateSyntaxError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;</span><span class=\"si\">%r</span><span class=\"s2\"> tag&#39;s argument should be in quotes&quot;</span> <span class=\"o\">%</span> <span class=\"n\">tag_name</span>\n        <span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">FormatTimeNode</span><span class=\"p\">(</span><span class=\"n\">date_to_be_formatted</span><span class=\"p\">,</span> <span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n</code></pre></div>\n<p>Devi anche cambiare il renderer per ritirare il contenuto attuale della proprietà <code class=\"docutils literal notranslate\"><span class=\"pre\">date_updated</span></code> dell’oggetto <code class=\"docutils literal notranslate\"><span class=\"pre\">blog_entry</span></code>. Questo può essere ottenuto usando la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Variable()</span></code> in <code class=\"docutils literal notranslate\"><span class=\"pre\">django.template</span></code>.</p>\n<p>Per usare la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Variable</span></code>, instanziala con il nome della variabile da risolvere, e poi chiama <code class=\"docutils literal notranslate\"><span class=\"pre\">variable.resolve(context)</span></code>.  Quindi, per esempio:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">FormatTimeNode</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">date_to_be_formatted</span><span class=\"p\">,</span> <span class=\"n\">format_string</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">date_to_be_formatted</span> <span class=\"o\">=</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Variable</span><span class=\"p\">(</span><span class=\"n\">date_to_be_formatted</span><span class=\"p\">)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span> <span class=\"o\">=</span> <span class=\"n\">format_string</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"k\">try</span><span class=\"p\">:</span>\n            <span class=\"n\">actual_date</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">date_to_be_formatted</span><span class=\"o\">.</span><span class=\"n\">resolve</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">)</span>\n            <span class=\"k\">return</span> <span class=\"n\">actual_date</span><span class=\"o\">.</span><span class=\"n\">strftime</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span><span class=\"p\">)</span>\n        <span class=\"k\">except</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">VariableDoesNotExist</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"s1\">&#39;&#39;</span>\n</code></pre></div>\n<p>La risoluzione della variabile solleverà una eccezione <code class=\"docutils literal notranslate\"><span class=\"pre\">VariableDoesNotExist</span></code> se non può risolvere la stringa che gli si passa nel contesto corrente della pagina.</p>\n</section>\n<section id=\"setting-a-variable-in-the-context\">\n<h3>Impostare una variabile nel contesto<a class=\"heading-anchor\" href=\"#setting-a-variable-in-the-context\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>L’esempio qui sopra mostra un valore. Generalmente, è tutto più flessibile se i template tag impostano le variabili di template invece di mostrare valori. In questo modo, gli autori di template possono riusare i valori che i tuoi tag di template creano.</p>\n<p>Per impostare una variabile nel contesto, usa l’assegnazione di dizionario sull’oggetto context nel metodo <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code>. Ecco una versione aggiornata di <code class=\"docutils literal notranslate\"><span class=\"pre\">CurrentTimeNode</span></code> che imposta una variabile di template chiamata <code class=\"docutils literal notranslate\"><span class=\"pre\">current_time</span></code> invece di mostrarla.</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">datetime</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">template</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CurrentTimeNode2</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">format_string</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span> <span class=\"o\">=</span> <span class=\"n\">format_string</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s1\">&#39;current_time&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">strftime</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"s1\">&#39;&#39;</span>\n</code></pre></div>\n<p>Nota che <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> restituisce una stringa vuota. <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> dovrebbe sempre restituire un output come stringa. Se tutto quel che il tag di template fa è impostare una variabile, <code class=\"docutils literal notranslate\"><span class=\"pre\">render()</span></code> dovrebbe restituire una stringa vuota.</p>\n<p>Ecco come useresti la nuova versione del tag:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">current_time</span> <span class=\"s2\">&quot;%Y-%m-%d %I:%M %p&quot;</span> <span class=\"cp\">%}</span><span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>The time is <span class=\"cp\">{{</span> <span class=\"nv\">current_time</span> <span class=\"cp\">}}</span>.<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<aside class=\"admonition-variable-scope-in-context admonition\">\n<p class=\"admonition-title\">Scope delle variabili nel contesto</p>\n<p>Ogni variabile impostata nel context sarà solo disponibile nello stesso <code class=\"docutils literal notranslate\"><span class=\"pre\">blocco</span></code> del template in cui è stata assegnata. Questo comportamento è intenzionale; fornisce uno scope per le variabili, in modo che non vadano in conflitto con il context in altri blocchi.</p>\n</aside>\n<p>Ma c’è un problema con <code class=\"docutils literal notranslate\"><span class=\"pre\">CurrentTimeNode2</span></code>: il nome di variabile <code class=\"docutils literal notranslate\"><span class=\"pre\">current_time</span></code> è hard-coded. Questo significa che dovrai accertarti che il tuo template non usi <code class=\"docutils literal notranslate\"><span class=\"pre\">{{</span> <span class=\"pre\">current_time</span> <span class=\"pre\">}}</span></code> da nessun altra parte, perchè <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">current_time</span> <span class=\"pre\">%}</span></code> sovrascriverà ciecamente quel nome di variabile. Una soluzione più pulita è fare in modo che il tag di template specifichi il nome della variabile di output, in questo modo:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">current_time</span> <span class=\"s2\">&quot;%Y-%m-%d %I:%M %p&quot;</span> <span class=\"k\">as</span> <span class=\"nv\">my_current_time</span> <span class=\"cp\">%}</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>The current time is <span class=\"cp\">{{</span> <span class=\"nv\">my_current_time</span> <span class=\"cp\">}}</span>.<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>Per fare ciò, dovrai rifattorizzare sia la funzione di compilazione che la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code>, così:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">re</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CurrentTimeNode3</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">format_string</span><span class=\"p\">,</span> <span class=\"n\">var_name</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span> <span class=\"o\">=</span> <span class=\"n\">format_string</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">var_name</span> <span class=\"o\">=</span> <span class=\"n\">var_name</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">var_name</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">datetime</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">strftime</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">format_string</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"s1\">&#39;&#39;</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">do_current_time</span><span class=\"p\">(</span><span class=\"n\">parser</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"p\">):</span>\n    <span class=\"c1\"># This version uses a regular expression to parse tag contents.</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"c1\"># Splitting by None == splitting by spaces.</span>\n        <span class=\"n\">tag_name</span><span class=\"p\">,</span> <span class=\"n\">arg</span> <span class=\"o\">=</span> <span class=\"n\">token</span><span class=\"o\">.</span><span class=\"n\">contents</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">(</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n    <span class=\"k\">except</span> <span class=\"ne\">ValueError</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">TemplateSyntaxError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;</span><span class=\"si\">%r</span><span class=\"s2\"> tag requires arguments&quot;</span> <span class=\"o\">%</span> <span class=\"n\">token</span><span class=\"o\">.</span><span class=\"n\">contents</span><span class=\"o\">.</span><span class=\"n\">split</span><span class=\"p\">()[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n        <span class=\"p\">)</span>\n    <span class=\"n\">m</span> <span class=\"o\">=</span> <span class=\"n\">re</span><span class=\"o\">.</span><span class=\"n\">search</span><span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s1\">&#39;(.*?) as (\\w+)&#39;</span><span class=\"p\">,</span> <span class=\"n\">arg</span><span class=\"p\">)</span>\n    <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">m</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">TemplateSyntaxError</span><span class=\"p\">(</span><span class=\"s2\">&quot;</span><span class=\"si\">%r</span><span class=\"s2\"> tag had invalid arguments&quot;</span> <span class=\"o\">%</span> <span class=\"n\">tag_name</span><span class=\"p\">)</span>\n    <span class=\"n\">format_string</span><span class=\"p\">,</span> <span class=\"n\">var_name</span> <span class=\"o\">=</span> <span class=\"n\">m</span><span class=\"o\">.</span><span class=\"n\">groups</span><span class=\"p\">()</span>\n    <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"p\">(</span><span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"ow\">and</span> <span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"ow\">in</span> <span class=\"p\">(</span><span class=\"s1\">&#39;&quot;&#39;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;&#39;&quot;</span><span class=\"p\">)):</span>\n        <span class=\"k\">raise</span> <span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">TemplateSyntaxError</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;</span><span class=\"si\">%r</span><span class=\"s2\"> tag&#39;s argument should be in quotes&quot;</span> <span class=\"o\">%</span> <span class=\"n\">tag_name</span>\n        <span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">CurrentTimeNode3</span><span class=\"p\">(</span><span class=\"n\">format_string</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">var_name</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>La differenza qui è che <code class=\"docutils literal notranslate\"><span class=\"pre\">do_current_time()</span></code> prende la stringa di formattazione ed il nome di variabile, passandole entrambe a <code class=\"docutils literal notranslate\"><span class=\"pre\">CurrentTimeNode3</span></code>.</p>\n<p>Infine, se hai solo bisogno di avere una sintassi semplice per il tuo template tag personalizzato che aggiorna il context, considera l’utilizzo dello shortcut <a class=\"reference internal\" href=\"#django.template.Library.simple_tag\" title=\"django.template.Library.simple_tag\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">simple_tag()</span></code></a>, che supporta l’assegnamento dei risultati del tag ad una variabile di template.</p>\n</section>\n<section id=\"parsing-until-another-block-tag\">\n<h3>Analisi fino ad un altro blocco tag<a class=\"heading-anchor\" href=\"#parsing-until-another-block-tag\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>I tag di template possono funzionare in tandem. Per esempio, il tag standard <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/#std-templatetag-comment\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code></a> nasconde ogni cosa fino a <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">endcomment</span> <span class=\"pre\">%}</span></code>. Per creare un tag di template come questo, usa <code class=\"docutils literal notranslate\"><span class=\"pre\">parser.parse()</span></code> nella tua funzione di compilazione.</p>\n<p>Ecco come potrebbe essere implementato un tag semplificato <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">do_comment</span><span class=\"p\">(</span><span class=\"n\">parser</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"p\">):</span>\n    <span class=\"n\">nodelist</span> <span class=\"o\">=</span> <span class=\"n\">parser</span><span class=\"o\">.</span><span class=\"n\">parse</span><span class=\"p\">((</span><span class=\"s1\">&#39;endcomment&#39;</span><span class=\"p\">,))</span>\n    <span class=\"n\">parser</span><span class=\"o\">.</span><span class=\"n\">delete_first_token</span><span class=\"p\">()</span>\n    <span class=\"k\">return</span> <span class=\"n\">CommentNode</span><span class=\"p\">()</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CommentNode</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"s1\">&#39;&#39;</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Nota</p>\n<p>L’implementazione reale di <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/#std-templatetag-comment\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code></a> è leggermente diversa nel fatto che permette a template tag rotti di apparire tra <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code> e``{% endcomment %}``. Lo fa chiamando <code class=\"docutils literal notranslate\"><span class=\"pre\">parser.skip_past('endcomment')</span></code> invece di <code class=\"docutils literal notranslate\"><span class=\"pre\">parser.parse(('endcomment',))</span></code> seguito da <code class=\"docutils literal notranslate\"><span class=\"pre\">parser.delete_first_token()</span></code>, evitando la generazione di una node list.</p>\n</aside>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">parser.parse()</span></code> prende una tupla di nomi di tag di blocco «fino a quali fare l’analisi». Restituisce una istanza di <code class=\"docutils literal notranslate\"><span class=\"pre\">django.template.NodeList</span></code>, che è una lista di tutti gli oggetti <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code> che il parser ha incontrato «prima» di incontrare un qualsiasi tag presente nella lista.</p>\n<p>In <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;nodelist</span> <span class=\"pre\">=</span> <span class=\"pre\">parser.parse(('endcomment',))&quot;</span></code> nell’esempio sopra, <code class=\"docutils literal notranslate\"><span class=\"pre\">nodelist</span></code> è una lista di nodi tra <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code> e <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">endcomment</span> <span class=\"pre\">%}</span></code>, senza contare <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code> e``{% endcomment %}`` stessi.</p>\n<p>Dopo che <code class=\"docutils literal notranslate\"><span class=\"pre\">parser.parse()</span></code> è stato chiamato, il parser non ha ancora «consumato» il tag <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">endcomment</span> <span class=\"pre\">%}</span></code>, quindi il codice ha bisogno di chiamare splicitamente``parser.delete_first_token()``.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">CommentNode.render()</span></code> restituisce una stringa vuota. Ogni cosa tra <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code> e <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">endcomment</span> <span class=\"pre\">%}</span></code> viene ignorata.</p>\n</section>\n<section id=\"parsing-until-another-block-tag-and-saving-contents\">\n<h3>Analizza fino ad un’altro tag, e salva i contenuti<a class=\"heading-anchor\" href=\"#parsing-until-another-block-tag-and-saving-contents\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Nell’esempio precedente, <code class=\"docutils literal notranslate\"><span class=\"pre\">do_comment()</span></code> ha scartato tutto quel che c’era tra  <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">comment</span> <span class=\"pre\">%}</span></code> e <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">endcomment</span> <span class=\"pre\">%}</span></code>. Invece di fare così, è possibile fare qualcosa con il codice che si trova tra i tra i tag.</p>\n<p>Per esempio, ecco un template tag personalizzato,  <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">upper</span> <span class=\"pre\">%}</span></code>, che rende maiuscolo tutto quel che c’è tra sè stesso e <code class=\"docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">endupper</span> <span class=\"pre\">%}</span></code>.</p>\n<p>Utilizzo:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">upper</span> <span class=\"cp\">%}</span>This will appear in uppercase, <span class=\"cp\">{{</span> <span class=\"nv\">your_name</span> <span class=\"cp\">}}</span>.<span class=\"cp\">{%</span> <span class=\"k\">endupper</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Come nell’esempio precedente, useremo <code class=\"docutils literal notranslate\"><span class=\"pre\">parser.parse()</span></code>. Ma questa volta, passeremo la <code class=\"docutils literal notranslate\"><span class=\"pre\">nodelist</span></code> risultante a <code class=\"docutils literal notranslate\"><span class=\"pre\">Node</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">do_upper</span><span class=\"p\">(</span><span class=\"n\">parser</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"p\">):</span>\n    <span class=\"n\">nodelist</span> <span class=\"o\">=</span> <span class=\"n\">parser</span><span class=\"o\">.</span><span class=\"n\">parse</span><span class=\"p\">((</span><span class=\"s1\">&#39;endupper&#39;</span><span class=\"p\">,))</span>\n    <span class=\"n\">parser</span><span class=\"o\">.</span><span class=\"n\">delete_first_token</span><span class=\"p\">()</span>\n    <span class=\"k\">return</span> <span class=\"n\">UpperNode</span><span class=\"p\">(</span><span class=\"n\">nodelist</span><span class=\"p\">)</span>\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">UpperNode</span><span class=\"p\">(</span><span class=\"n\">template</span><span class=\"o\">.</span><span class=\"n\">Node</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">nodelist</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">nodelist</span> <span class=\"o\">=</span> <span class=\"n\">nodelist</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">render</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"n\">output</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">nodelist</span><span class=\"o\">.</span><span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">context</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">output</span><span class=\"o\">.</span><span class=\"n\">upper</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>L’unico concetto nuovo qui è <code class=\"docutils literal notranslate\"><span class=\"pre\">self.nodelist.render(context)</span></code> in <code class=\"docutils literal notranslate\"><span class=\"pre\">UpperNode.render()</span></code>.</p>\n<p>Per vedere più esempi di rendering complesso, guarda il codice complesso di <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/#std-templatetag-for\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">for</span> <span class=\"pre\">%}</span></code></a> in <code class=\"docutils literal notranslate\"><span class=\"pre\">django/template/defaulttags.py</span></code> e <a class=\"reference internal\" href=\"/it/4.1/ref/templates/builtins/#std-templatetag-if\"><code class=\"xref std std-ttag docutils literal notranslate\"><span class=\"pre\">{%</span> <span class=\"pre\">if</span> <span class=\"pre\">%}</span></code></a>  in <code class=\"docutils literal notranslate\"><span class=\"pre\">django/template/smartif.py</span></code>.</p>\n</section>\n</section>","rootId":"how-to-create-custom-template-tags-and-filters","toc":[{"title":"Layout del codice","anchor":"code-layout","children":[]},{"title":"Scrivere filtri template personalizzati","anchor":"writing-custom-template-filters","children":[{"title":"Registrazione di filtri personalizzati","anchor":"registering-custom-filters","children":[]},{"title":"Template filtri che si aspettano delle stringhe","anchor":"template-filters-that-expect-strings","children":[]},{"title":"Filtri e auto escaping","anchor":"filters-and-auto-escaping","children":[]},{"title":"Filtri e time zones","anchor":"filters-and-time-zones","children":[]}]},{"title":"Scrivere template tag personalizzati","anchor":"writing-custom-template-tags","children":[{"title":"Semplici tag","anchor":"simple-tags","children":[]},{"title":"Tag di inclusione","anchor":"inclusion-tags","children":[]},{"title":"Tag di template personalizzati avanzati","anchor":"advanced-custom-template-tags","children":[]},{"title":"Una rapida panoramica","anchor":"a-quick-overview","children":[]},{"title":"Scrivere la funzione di compilazione","anchor":"writing-the-compilation-function","children":[]},{"title":"Scrivere il renderer","anchor":"writing-the-renderer","children":[]},{"title":"Considerazioni sull’auto-escape","anchor":"auto-escaping-considerations","children":[]},{"title":"Considerazioni sulla sicurezza","anchor":"thread-safety-considerations","children":[]},{"title":"Registrare il tag","anchor":"registering-the-tag","children":[]},{"title":"Passare variabili del template ai tag","anchor":"passing-template-variables-to-the-tag","children":[]},{"title":"Impostare una variabile nel contesto","anchor":"setting-a-variable-in-the-context","children":[]},{"title":"Analisi fino ad un altro blocco tag","anchor":"parsing-until-another-block-tag","children":[]},{"title":"Analizza fino ad un’altro tag, e salva i contenuti","anchor":"parsing-until-another-block-tag-and-saving-contents","children":[]}]}],"breadcrumbs":[{"docname":"howto/index","title":"guide «How-to»","url":"/it/4.1/howto/"}],"prev":{"docname":"howto/custom-template-backend","title":"Come implementare un backend per template personalizzato","url":"/it/4.1/howto/custom-template-backend/"},"next":{"docname":"howto/custom-file-storage","title":"Come scrivere una storage class personalizzata","url":"/it/4.1/howto/custom-file-storage/"},"formats":{"html":"/it/4.1/howto/custom-template-tags/","markdown":"/it/4.1/howto/custom-template-tags.md","json":"/it/4.1/howto/custom-template-tags.json"},"source":"https://github.com/django/django/blob/stable/4.1.x/docs/howto/custom-template-tags.txt","official":"https://docs.djangoproject.com/it/4.1/howto/custom-template-tags/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}