italia/design-django-theme

Bootstrap Italia template for Django

design
django

Join the #design-cms-themes channel Get invited Design on forum.italia.it Downloads

Bootstrap Italia template for Django

Completamente open-source, costruita sulle fondamenta di Bootstrap Italia, di cui eredita tutte le funzionalità, componenti, griglie e classi di utilità, secondo le Linee Guida di Design per i siti web della Pubblica Amministrazione. Bootstrap Italia usa i pattern e i componenti definiti nello UI Kit di Designers Italia e li trasforma in codice già pronto all'uso.

Questa libreria per il framework Python Django fornisce lo schema di default del template, opportunamente diviso in blocchi di cui poter fare l'overload, al fine di dotare il proprio progetto di una interfaccia grafica che rispetti le Linee guida di design per i servizi web della Pubblica Amministrazione.

QUI è possibile prendere visione del codice sorgente per l'implementazione di tutti i componenti grafici messi a disposizione.

Installazione

pip install design-django-theme
  • In settings.py INSTALLED_APPS inserire bootstrap_italia_template.

Utilizzo

python manage.py collectstatic
  • Nel template del progetto, creare un file base.html (scegliere il nome preferito) ed eseguire l'extends del file bootstrap-italia-base.html. Questa sarà la base grafica (il file è concepito quasi come un file di configurazione), comune a tutte (o quasi) le pagine del sistema;
  • In base.html eseguire l'overload dei blocchi, al fine di personalizzare le sezioni di interesse (es. il nome dell'Ente/Organizzazione, il logo, ecc...);
  • Ogni pagina del proprio progetto dovrà estendere base.html ed effettuare l'overload del blocco {% container %}, ereditando, cosi, le impostazioni di <header> e <footer> opportunamente personalizzate.

Formato data nel datepicker

Per personalizzare il formato della data utilizzato nel widget datepicker (calendario) dei form, effettuare l'override del parametro JS_DEFAULT_DATE_FORMAT nel file settings del progetto. Il valore di default è "dd/MM/yyyy".

Stile e CSS/SCSS

Per la personalizzazione dello stile del template (colori, dimensioni, sfondi), si consiglia l'utilizzo di SASS 3 (Syntactically Awesome Style Sheets), in modo da essere in grado di agire in ambito responsive.

Può essere utile django-sass-processor.

Una volta installate le librerie, sarà possibile integrare fogli di stile .scss e importarli nelle proprie pagine effettuando l'overload del blocco {% extra_head %}.

CDN vs local

E' possibile recuperare i file statici (css, js, svg) da una CDN. Nel settings.py del proprio progetto basta customizzare i seguenti parametri:

  • DJANGO_BOOTSTRAP_ITALIA_USE_CDN (default False);
  • DJANGO_BOOTSTRAP_ITALIA_CDN (default https://cdn.jsdelivr.net/npm/[email protected]/dist);

Descrizione dei blocchi

I blocchi sono elencati in ordine di "apparizione" nel file bootstrap-italia-base.html.

Block Descrizione
{% block bootstrap_italia_loader %} Script di Bootstrap Italia (se si sceglie di non includere il bundle)
{% block page_title %} Tag della pagina</td> </tr> <tr> <td><strong>{% block page_meta_description %}</strong></td> <td>tag <meta-description> della pagina</td> </tr> <tr> <td><strong>{% block page_meta_keywords %}</strong></td> <td>tag <meta-keywords> della pagina</td> </tr> <tr> <td><strong>{% block page_meta_robots %}</strong></td> <td>tag <meta-robots> della pagina</td> </tr> <tr> <td><strong>{% block extra_head %}</strong></td> <td>Extra CSS o Javascript</td> </tr> <tr> <td><strong>{% block header_wrapper %}</strong></td> <td>Intero blocco Header</td> </tr> <tr> <td><strong>{% block header_slim_wrapper %}</strong></td> <td>Striscia top in Header</td> </tr> <tr> <td><strong>{% block header_center_wrapper_columns %}</strong></td> <td>Classe per definizione colonne in griglia in "it-header-center-wrapper"</td> </tr> <tr> <td><strong>{% block header_slim_top_left %}</strong></td> <td>Striscia top left che avvolge header_slim_org_name</td> </tr> <tr> <td><strong>{% block header_slim_org_name %}</strong></td> <td>Nome organizzazione in Header top</td> </tr> <tr> <td><strong>{% block header_slim_mobile_org_name %}</strong></td> <td>Nome organizzazione in Header top (mobile)</td> </tr> <tr> <td><strong>{% block header_mobile_arrow %}</strong></td> <td>Icona freccia sub-menu in Header top (mobile)</td> </tr> <tr> <td><strong>{% block header_mobile_slim_menu %}</strong></td> <td>Sub-menu nome organizzazione (mobile)</td> </tr> <tr> <td><strong>{% block header_slim_right_zone %}</strong></td> <td>Area di destra in Header top</td> </tr> <tr> <td><strong>{% block header_slim_sub_menu %}</strong></td> <td>Sub-menu area di destra in Header top</td> </tr> <tr> <td><strong>{% block header_slim_buttons %}</strong></td> <td>Button area di destra in Header top</td> </tr> <tr> <td><strong>{% block header_brand_wrapper %}</strong></td> <td>Wrapper div del logo</td> </tr> <tr> <td><strong>{% block header_brand_text %}</strong></td> <td>Wrapper div del testo del logo</td> </tr> <tr> <td><strong>{% block header_center_logo %}</strong></td> <td>Header logo principale</td> </tr> <tr> <td><strong>{% block header_center_org_name %}</strong></td> <td>Nome organizzazione principale in Header</td> </tr> <tr> <td><strong>{% block header_center_org_subname %}</strong></td> <td>Descrizione organizzazione in Header</td> </tr> <tr> <td><strong>{% block header_center_right_zone %}</strong></td> <td>Area di destra sezione principale Header</td> </tr> <tr> <td><strong>{% block header_center_social %}</strong></td> <td>Area icone social in sezione principale Header</td> </tr> <tr> <td><strong>{% block header_center_search %}</strong></td> <td>Area "Cerca" in sezione principale Header</td> </tr> <tr> <td><strong>{% block header_center_search_text %}</strong></td> <td>Area di testo in "Cerca"</td> </tr> <tr> <td><strong>{% block header_center_search_word %}</strong></td> <td>Testo "Cerca"</td> </tr> <tr> <td><strong>{% block header_center_search_icon %}</strong></td> <td>Icona tasto "Cerca"</td> </tr> <tr> <td><strong>{% block main_menu %}</strong></td> <td>Menu principale in Header</td> </tr> <tr> <td><strong>{% block menu_links %}</strong></td> <td>Voci del menu principale</td> </tr> <tr> <td><strong>{% block messages %}</strong></td> <td>Messaggi di sistema</td> </tr> <tr> <td><strong>{% block centered_messages %}</strong></td> <td>Messaggi di sistema, centrati, con margin e padding settati</td> </tr> <tr> <td><strong>{% block container %}</strong></td> <td>Contenuto della pagina, senza padding e margin</td> </tr> <tr> <td><strong>{% block centered_container %}</strong></td> <td>Contenuto della pagina, centrato, con margin e padding settati</td> </tr> <tr> <td><strong>{% block footer %}</strong></td> <td>Area footer</td> </tr> <tr> <td><strong>{% block footer_top_section %}</strong></td> <td>Striscia top in Footer</td> </tr> <tr> <td><strong>{% block footer_logo %}</strong></td> <td>Logo Footer</td> </tr> <tr> <td><strong>{% block footer_org_text %}</strong></td> <td>Area nome organizzazione in Footer</td> </tr> <tr> <td><strong>{% block footer_org_name %}</strong></td> <td>Nome organizzazione in Footer</td> </tr> <tr> <td><strong>{% block footer_org_subname %}</strong></td> <td>Descrizione organizzazione in Footer</td> </tr> <tr> <td><strong>{% block footer_menu_section %}</strong></td> <td>Sezione menu centrali in Footer</td> </tr> <tr> <td><strong>{% block first_column %}</strong></td> <td>Prima colonna in sezione centrale in Footer</td> </tr> <tr> <td><strong>{% block second_column %}</strong></td> <td>Seconda colonna in sezione centrale in Footer</td> </tr> <tr> <td><strong>{% block third_column %}</strong></td> <td>Terza colonna in sezione centrale in Footer</td> </tr> <tr> <td><strong>{% block fourth_column %}</strong></td> <td>Quarta colonna in sezione centrale in Footer</td> </tr> <tr> <td><strong>{% block footer_contacts_section %}</strong></td> <td>Sezione contatti in Footer</td> </tr> <tr> <td><strong>{% block footer_bottom %}</strong></td> <td>Striscia bottom in Footer</td> </tr> <tr> <td><strong>{% block footer_bottom_content %}</strong></td> <td>Contenuto striscia bottom in Footer</td> </tr> <tr> <td><strong>{% block bottom_scripts %}</strong></td> <td>Javascripts</td> </tr> <tr> <td><strong>{% block extra_scripts %}</strong></td> <td>Javascript aggiuntivi a fine pagina</td> </tr> </tbody> </table> <h2>Esempio di base.html</h2> <div class="codehilite"><pre><span></span><code><span class="x"><!-- Extends default Bootstrap Italia template --></span> <span class="cp">{%</span> <span class="k">extends</span> <span class="s1">'bootstrap-italia-base.html'</span> <span class="cp">%}</span> <span class="x"><!-- From app django-sass-processor --></span> <span class="cp">{%</span> <span class="k">load</span> <span class="nv">sass_tags</span> <span class="cp">%}</span> <span class="cp">{%</span> <span class="k">load</span> <span class="nv">static</span> <span class="cp">%}</span> <span class="x"><!-- Page Title --></span> <span class="cp">{%</span> <span class="k">block</span> <span class="nv">page_title</span> <span class="cp">%}</span> <span class="x">Università della Calabria</span> <span class="cp">{%</span> <span class="k">endblock</span> <span class="nv">page_title</span> <span class="cp">%}</span> <span class="x"><!-- My custom scss sheet --></span> <span class="cp">{%</span> <span class="k">block</span> <span class="nv">extra_head</span> <span class="cp">%}</span> <span class="x"><link rel="stylesheet" href="</span><span class="cp">{%</span> <span class="k">sass_src</span> <span class="s1">'css/unical-style.scss'</span> <span class="cp">%}</span><span class="x">" type="text/css" /></span> <span class="cp">{%</span> <span class="k">endblock</span> <span class="nv">extra_head</span> <span class="cp">%}</span> <span class="x"><!-- URL link top left --></span> <span class="cp">{%</span> <span class="k">block</span> <span class="nv">header_slim_org_url</span> <span class="cp">%}</span> <span class="x">https://www.unical.it</span> <span class="cp">{%</span> <span class="k">endblock</span> <span class="nv">header_slim_org_url</span> <span class="cp">%}</span> <span class="x"><!-- Name top left --></span> <span class="cp">{%</span> <span class="k">block</span> <span class="nv">header_slim_org_name</span> <span class="cp">%}</span> <span class="x">Università della Calabria</span> <span class="cp">{%</span> <span class="k">endblock</span> <span class="nv">header_slim_org_name</span> <span class="cp">%}</span> <span class="x"><!-- Mobile slim_org_name --></span> <span class="cp">{%</span> <span class="k">block</span> <span class="nv">header_slim_mobile_org_name</span> <span class="cp">%}</span> <span class="x">Università della Calabria</span> <span class="cp">{%</span> <span class="k">endblock</span> <span class="nv">header_slim_mobile_org_name</span> <span class="cp">%}</span> <span class="x"><!-- Make empty areas --></span> <span class="cp">{%</span> <span class="k">block</span> <span class="nv">header_mobile_arrow</span> <span class="cp">%}{%</span> <span class="k">endblock</span> <span class="nv">header_mobile_arrow</span> <span class="cp">%}</span> <span class="cp">{%</span> <span class="k">block</span> <span class="nv">header_mobile_slim_menu</span> <span class="cp">%}{%</span> <span class="k">endblock</span> <span class="nv">header_mobile_slim_menu</span> <span class="cp">%}</span> <span class="x"><!-- Logo in Header --></span> <span class="cp">{%</span> <span class="k">block</span> <span class="nv">header_center_logo</span> <span class="cp">%}</span> <span class="x"><img class="icon" src="</span><span class="cp">{%</span> <span class="k">static</span> <span class="s1">'images/logo.png'</span> <span class="cp">%}</span><span class="x">" /></span> <span class="cp">{%</span> <span class="k">endblock</span> <span class="nv">header_center_logo</span> <span class="cp">%}</span> <span class="x"><!-- Organization name in Header --></span> <span class="cp">{%</span> <span class="k">block</span> <span class="nv">header_center_org_name</span> <span class="cp">%}</span> <span class="x">Università della Calabria</span> <span class="cp">{%</span> <span class="k">endblock</span> <span class="nv">header_center_org_name</span> <span class="cp">%}</span> <span class="x"><!-- Organization description in Header --></span> <span class="cp">{%</span> <span class="k">block</span> <span class="nv">header_center_org_subname</span> <span class="cp">%}</span> <span class="x">Il Campus per eccellenza</span> <span class="cp">{%</span> <span class="k">endblock</span> <span class="nv">header_center_org_subname</span> <span class="cp">%}</span> <span class="x"><!-- Logo in Footer --></span> <span class="cp">{%</span> <span class="k">block</span> <span class="nv">footer_logo</span> <span class="cp">%}</span> <span class="x"><img class="icon" src="</span><span class="cp">{%</span> <span class="k">static</span> <span class="s1">'images/logo_white.png'</span> <span class="cp">%}</span><span class="x">" /></span> <span class="cp">{%</span> <span class="k">endblock</span> <span class="nv">footer_logo</span> <span class="cp">%}</span> <span class="x"><!-- Organization name in Footer --></span> <span class="cp">{%</span> <span class="k">block</span> <span class="nv">footer_org_name</span> <span class="cp">%}</span> <span class="x">Università della Calabria</span> <span class="cp">{%</span> <span class="k">endblock</span> <span class="nv">footer_org_name</span> <span class="cp">%}</span> <span class="x"><!-- Organization name in Footer --></span> <span class="cp">{%</span> <span class="k">block</span> <span class="nv">footer_org_subname</span> <span class="cp">%}</span> <span class="x">Il Campus per eccellenza</span> <span class="cp">{%</span> <span class="k">endblock</span> <span class="nv">footer_org_subname</span> <span class="cp">%}</span> </code></pre></div> <h2>Widget per i form fields di Django</h2> <p>Definiti i <a href="https://docs.djangoproject.com/en/4.2/ref/forms/widgets/">Django widgets</a> per l'adeguamento grafico dei form alle linee guida di <strong>Bootstrap Italia</strong>.</p> <p><img alt="Radio Box" src="data/gallery/widget_radio.png" /> <em>Radio box field</em></p> <p><img alt="Select Box" src="data/gallery/widget_select.png" /> <em>Select box field</em></p> <p><img alt="Date Field" src="data/gallery/widget_date.png" /> <em>Date field</em></p> <p>Per l'utilizzo dei <a href="https://docs.djangoproject.com/en/4.2/topics/forms/formsets/">Django Formset</a> si consiglia l'utilizzo nel proprio progetto della libreria <a href="https://github.com/UniversitaDellaCalabria/django-form-builder.git">django-form-builder</a> dell'<a href="https://github.com/UniversitaDellaCalabria">Università della Calabria</a>.</p> <p>Viene fornito a tale scopo un widget ad-hoc.</p> <p><img alt="Formset Field" src="data/gallery/widget_formset.png" /> <em>Formset field</em></p> <h2>Galleria</h2> <p><img alt="Home" src="data/gallery/default.png" /> <em><strong>Frontend</strong>: Schermata di default del template</em></p></article> </div> </div> <div> <div class="lg:ml-6 stats stats-vertical"> <div class="stat"> <div class="stat-figure text-info"> <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-star" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path d="M12 17.75l-6.172 3.245l1.179 -6.873l-5 -4.867l6.9 -1l3.086 -6.253l3.086 6.253l6.9 1l-5 4.867l1.179 6.873z" /> </svg> </div> <div class="stat-title">Stars</div> <div class="stat-value text-info">42</div> <div class="stat-desc">100.00% more than last month</div> </div> <div class="stat"> <div class="stat-figure text-primary"> <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-git-fork" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path d="M12 18m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /> <path d="M7 6m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /> <path d="M17 6m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /> <path d="M7 8v2a2 2 0 0 0 2 2h6a2 2 0 0 0 2 -2v-2" /> <path d="M12 12l0 4" /> </svg> </div> <div class="stat-title">Forks</div> <div class="stat-value text-primary">16</div> </div> <div class="stat"> <div class="stat-figure text-error"> <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-bug" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path d="M9 9v-1a3 3 0 0 1 6 0v1" /> <path d="M8 9h8a6 6 0 0 1 1 3v3a5 5 0 0 1 -10 0v-3a6 6 0 0 1 1 -3" /> <path d="M3 13l4 0" /> <path d="M17 13l4 0" /> <path d="M12 20l0 -6" /> <path d="M4 19l3.35 -2" /> <path d="M20 19l-3.35 -2" /> <path d="M4 7l3.75 2.4" /> <path d="M20 7l-3.75 2.4" /> </svg> </div> <div class="stat-title">Open Issues</div> <div class="stat-value text-error">0</div> </div> </div> </div> </div> </div> </div> <footer class="footer footer-center bg-neutral p-10"> <div> <a href="/"> <img src="/static/images/logo.f063f0c760fb.png" class="w-32" alt="Django.wtf"> </a> <p class="text-white">Made for the Django Community</p> </div> </footer> <noscript> <img alt="django-wtf logo" src="https://s.depode.com/ingress/7ca0f5ff-8ef2-45fb-9718-37d34cddfe79/pixel.gif"> </noscript> <script defer src="https://s.depode.com/ingress/7ca0f5ff-8ef2-45fb-9718-37d34cddfe79/script.js"></script> <script src="https://unpkg.com/htmx.org@1.9.11"></script> </body> <script src="https://cdnjs.cloudflare.com/ajax/libs/medium-zoom/1.0.6/medium-zoom.min.js" integrity="sha512-N9IJRoc3LaP3NDoiGkcPa4gG94kapGpaA5Zq9/Dr04uf5TbLFU5q0o8AbRhLKUUlp8QFS2u7S+Yti0U7QtuZvQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script> const images = Array.from(document.querySelectorAll(".prose img")); console.log(images) images.forEach(img => { mediumZoom(img, { margin: 0, /* The space outside the zoomed image */ scrollOffset: 40, /* The number of pixels to scroll to close the zoom */ container: null, /* The viewport to render the zoom in */ template: null /* The template element to display on zoom */ }); }); </script> </html> <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>