Come generare un sito statico con Zola

Zola è un generatore di siti statici (GSS) semplice ma potente, ed è ciò che rende possibile questo sito. In questo articolo vediamo come generare un semplice blog partendo da zero, pronto per essere caricato sull'hosting prescelto. È importante tenere presente che questa è una guida di base e non sostituisce in alcun modo la documentazione ufficiale.

Ecco uno spoiler del risultato finale:

Blog generato con il tema slim e sommarii attivi Blog generato con il tema slim e sommarii attivi

Un foglio bianco: zola init

Un buon primo passo è creare la struttura della cartella di lavoro. In Zola si può generare tranquillamente in locale, senza bisogno di scaricare scheletri preesistenti da internet. Lanciando il comando in questione sono richieste alcune informazioni di base, come l'URL di rilascio e l'attivazione o meno di alcune funzionalità facoltative come l'evidenziazione della sintassi. Come fa notare il programma non sono informazioni scolpite nella roccia, ma si possono modificare facilmente nel file config.toml.

Descriviamo un secondo le cartelle create:

  • content: sono contenuti gli articoli formattati in Markdown
  • sass: sono presenti i file Sass da compilare; la struttura viene mantenuta nella cartella compilata (e.g. sass/css/base.sass -> public/css/base.css)
  • static: è presente ogni genere di file da mantenere inalterato; come per sass la struttura viene mantenuta
  • templates: sono presenti i file di template per generare il sito; se presenti in omonimia con i file del tema attivo hanno la precedenza
  • themes: sono presenti le cartelle dei temi; approfondimento più avanti
  • public (non creata in questo passaggio): cartella di destinazione dei file compilati con zola build

I template: non scrivere due volte

Il template è alla base di ogni GSS, perché si preoccupa di generare le pagine in un dato un formato fisso, senza duplicare l'HTML come si farebbe scrivendolo a mano come i primitivi. In più questo strumento ha funzioni simili a quelle che avrebbe un linguaggio lato server come PHP, occupandosi della generazione di elementi tradizionalmente "dinamici", come l'elenco delle notizie di un sito.

In Zola sono dei file con estensione .html, che però contengono istruzioni Tera, un linguaggio di template in stile Jinja2 e Django. Questi file sono contenuti nella cartella templates.

Ci sono alcuni nomi di file predefiniti:

  • index.html: usato soltanto per il file index.html della cartella di root
  • section.html: usato per il file index.html di ogni sottocartella di content che contiene il file di sezione _index.md.
  • page.html: usato per il file HTML di ogni articolo

In più esistono alcuni template impliciti: atom.xml/rss.xml per i feed, sitemap.xml e robots.txt. Se esiste un file con lo stesso nome in templates allora quello avrà la precedenza, altrimenti sarà usato quello predefinito.

In base alla posizione da cui viene chiamato, il template avrà a disposizione una diversa variabile per far accesso alle informazioni per generare la pagina. Se viene chiamato da una sezione avrà a disposizione un oggetto section con tutte le informazioni sulla stessa, tra cui quella sulle pagine di quella sezione. Se viene chiamato da una pagina avrà accesso ad un oggetto page, con informazioni come il contenuto della pagina, la data e ad altre informazioni utili per la generazione della stessa. In questa pagina l'approfondimento di tutti gli attributi.

Per accedere agli attributi di questi oggetti predefiniti si usa una notazione puntata stile Java. Per stampare uno qualsiasi degli attributi, lo si racciude tra {{ }}, ad esempio:

{{ page.content }}

I costrutti fondamentali usati sono i cicli e i controlli condizionali.

Il ciclo for (a tutti gli effetti un for each) è particolarmente utile per accedere a tutte le pagine di una sezione, il vettore section.pages, che sarà ordinato secondo l'ordine specificato dall'attributo sort_by nel file di sezione (vedi più avanti). Ad esempio:

{% for post in section.pages %}
  <h1><a href="{{ post.permalink }}">{{ post.title }}</a></h1>
{% endfor %}

Il costrutto if è usato specialmente per condizionare la pagina della presenza o meno di un elemento. Se volessi ad esempio mostrare la data soltanto se è definita per la pagina potrei fare qualcosa come:

{% if page.date %}
<span>{{ page.date }}</span>
{% endif %}

Questa non è in alcun modo una guida completa, anzi è solo uno spunto ad approfondire nella documentazione ufficale Tera.

Sezioni: un po' d'ordine

Una sezione in Zola è definita come una sottocartella di content che contiene un file _index.md. Anche la cartella radice del sito si comporta come una sezione, ma il file _index.md può essere implicito. Tutte le configurazioni specifiche per la sezione si devono fare nel preambolo di questo file (la parte racchiusa tra +++).

Una sezione vede soltanto i file presenti nella sua cartella, più i file di tutte le sue sottosezioni dove è dichiarato l'attributo trasparent = true. È utile tenere presente che spesso i temi non usano sottosezioni, ma invece richiedono tutte le pagine del sito nella stessa cartella. La suddivisione logica sarà poi gestita tramite categorie e tag.

Una configurazione minima può assomigliare alla seguente:

+++
title = "Sottosezione"
sort_by = "date"
# Attiva la paginazione, deve essere supportata dai template del tema
paginate_by = 10
# Template non standard per l'indice della sezione
template = "custom_section.html"
# Template non standard per le pagine della sezione, il template della pagina stessa ha maggiore priorità
page_template = "custom_page.html"
+++

È consigliabile attenersi ai nomi standard, ma si possono comunque modificare per esempio per creare una pagina con un'organizzazione non standard, oppure per adattarsi alle convenzioni di un tema non nostro.

L'elenco completo di attributi supportati è disponibile qui.

Pagine: i contenuti

Una pagina (o articolo) in Zola è qualsiasi file .md in content che non sia _index.md. È qui il posto dove andremo a scrivere gli articoli in Markdown, i quali saranno poi tradotti in HTML e incorporati nel template.

È possibile creare un sommario ad uso del template specificando in un punto della pagina il commento HTML <!--more-->. A questo punto la variabile summary di page sarà disponibile al template, che potrà usarla ad esempio per generare una lista degli articoli con una breve anteprima.

Anche le pagine possiedono un preambolo come le sezioni, dove è possibile specificare informazioni specifiche della pagina. Dato che questa parte può diventare piuttosto consistente, può avere senso creare una bozza da duplicare con tutti i parametri usati di solito, eliminando di volta in volta quelli inutili.

Ecco in questo caso una configurazione estrema:

+++
title = "Titolo del mio bellissimo articolo"
# La data si imposta con formato americano, il tema ci penserà in seguito a convertirla
date = 2020-07-15
# Bozza, per stabilire se deve essere compilata. Per consentire la compilazione si può omettere.
draft = true
# [Facoltativo] Forza un percorso diverso da quello dedotto in automatico, a partire dalla cartella radice
path = "circa.html"
# [Facoltativo] Template per la pagina. Ha la precedenza su quello generale della sezione.
template = "bio.html"
# Impostazioni per generare le tassonomie – categorie e tag. Sono le stesse presenti in config.toml e devono essere supportate dal tema.
[taxonomies]
categorie = [ "Biografia", "Generale"]
tags = [ "Circa", "Cazzimé"]
# Eventuali attributi personalizzati (in genere per il tema)
[extra]
display_date = false
+++
## Bel sottotitolo
Tanto bel testo
Tanto bel testo
Tanto bel testo

L'elenco completo di attributi supportati è disponibile qui.

I temi: non reinventiamo la ruota

Un tema in Zola è a tutti gli effetti un sito, con tutta la struttura di cartelle che abbiamo visto, che risiede in una sottocartella di themes. Per attivarne uno basta specificare l'attributo theme = "sottocartella di themes" nel file di configurazione config.toml.

Quando un tema è attivo il sito vedrà come propri tutti i template del tema e potrà utilizzarli per renderizzare pagine e sezioni, eventualmente specificando il file corretto nel preambolo. È importante ricordare però che se esiste già un altro file omonimo nelle corrispondenti cartelle di primo livello del sito, allora quest'ultimo avrà la precedenza rispetto al file del tema. Questo comportamento si può sfruttare copiando un file del tema per una piccola modifica o personalizzazione.

Un elenco di temi è mantenuto in questo repository GitHub. Per installarne uno è sufficiente clonare il rispettivo repo nella cartella themes.

Sporchiamoci le mani e testiamo: zola serve

A questo punto abbiamo tutte le informazioni per creare un sito partendo da un tema esistente.

Il processo è più o meno il seguente:

  1. scelgo il tema dal repository e lo clono nella cartella themes
  2. leggo la (minima) documentazione specifica del tema (essenzialmente le variabili supportate nell'[extra] del config.toml)
  3. attivo il tema (attributo theme) e setto le variabili necessarie nel config.toml
  4. inizio a scrivere contenuti utili (si spera) nelle cartelle predisposte

Vediamo un esempio con il tema slim.

La scelta

Creiamo la struttura base con zola init in una cartella vuota, poi ci spostiamo nella cartella themes e cloniamo il tema con il comando git clone https://github.com/jameshclrk/zola-slim slim.

La lettura

Dal file README.md vediamo cosa possiamo configurare in config.toml.

Sono supportati i tags:

taxonomies = [
    {name = "tags", paginate_by = 5, rss = true}
]

E ci sono alcune impostazioni facoltative:

[extra]
# Mostra un sommario dell'articolo nella lista
slim_summary = true
# Mostra il contenuto dell'articola nella lista
slim_content = false
# Elenco di link da inserire nella parte superiore del menu
slim_menu = [
    {url = "$BASE_URL/tags/", name = "Tags"}
]
# Elenco di link da inserire nella parte inferiore del menu
slim_social = [
    {url = "https://github.com/bagnacauda", name = "GitHub"}
]
# Testo nel footer, se non definita testo di default 'Powered by Zola'
slim_footer = "Licenza: CC BY-SA 4.0 (tranne ove diversamente specificato)"

La configurazione

Una volta comprese le opzioni facoltative il file config.toml completo sarà del tipo:

# URL su cui sarà rilasciato il sito, finché si lavora in locale con zola serve non... serve
base_url = "https://www.ilmiobelsito.it"

# Informazioni generali
title = "Il mio bel sito"
description = "È proprio un bel sito"

default_language = "it"

# Compilare o meno i file SASS nella cartella sass
compile_sass = true

# Se evidenziare o meno la sintassi
# highlight_theme serve per selezionare il tema con un valore tra quelli supportati da zola
highlight_code = true
highlight_theme = "gruvbox-dark"

# Generare o meno il feed
generate_feed = true

# Indice per un uso successivo con JavaScript
build_search_index = false

# Tema, nome della cartella in themes
theme = "slim"

taxonomies = [
    {name = "tags", paginate_by = 5, rss = true},
]

[extra]
# Mostra un sommario dell'articolo nella lista
slim_summary = true
# Mostra il contenuto dell'articola nella lista
slim_content = false
# Elenco di link da inserire nella parte superiore del menu
slim_menu = [
    {url = "$BASE_URL/tags/", name = "Tags"}
]
# Elenco di link da inserire nella parte inferiore del menu
slim_social = [
    {url = "https://github.com/torvalds", name = "GitHub"}
]
# Testo nel footer, se non definita testo di default 'Powered by Zola'
slim_footer = "Licenza: CC BY-SA 4.0 (tranne ove diversamente specificato)"

La scrittura

A questo punto non resta che popolare il sito di articoli pseudoutili. Guardando la cartella content del tema (in themes/slim), che funge da esempio, ci accorgiamo che il tema ha bisogno di avere tutti i suoi file nella radice di content e che non supporta le sezioni, dato che non esiste un file section.html in templates.

Per una rapida demo basta copiare questi articoli nella cartella content radice, tornare alla cartella che contiene il config.toml e dare il comando zola serve. A questo punto il sito è visibile all'indirizzo http://127.0.0.1:1111.

È anche sensibile alle modifiche, supportando l'aggiornamento automatico, per cui provate a modificare i titoli degli articoli o i tag per vedere cosa succede.

Potete anche provare ad attivare e disattivare il sommario nella configurazione, ma quando si tocca questo file bisogna riavviare zola serve a mano.

Problemi, modifiche e personalizzazioni

Non vi ho fatto tutto lo spiegone sui template solo per sembrare intelligente, ma perché inevitabilmente troverete delle caratteristiche che non vi piacciono. Quello che a me dà più fastidio di tutti è il formato della data.

Ora, non vi ho detto l'esatto comando per formattare la data perché è un dettaglio, ma avete tutti gli strumenti per trovarlo nella documentazione Tera.

Per scoprire qual è il file che stampa la data della pagina si può usare il seguente comando (una volta spostati nella cartella templates del tema):

$ find . -type f -exec grep -H page.date {} \;

La sintassi di find è un po' oscura, ma essenzialmente eseguiamo grep (-H per stampare il nome file che matcha) su ogni file (-type f) di questa e delle sottocartelle. {} è un segnaposto per il nome del file corrente.

Per il tema slim l'output sarà il seguente:

./macros.html:    <span class="post-date">{{ page.date | date(format="%B %d, %Y") }}</span>

Usa una sintassi molto simile (non sono sicuro se identica) al comando UNIX date.

A questo punto si può modificare ad esempio così:

<span class="post-date">{{ page.date | date(format="%d/%m/%Y") }}</span>

Il rilascio: zola build

Eccovi pronti a pubblicare il sito che avete costruito e sul quale nessuno inciamperà neanche per sbaglio (ma sempre meglio che scrivere contenuti come contoterzista aggratis per Facebook, no?). Il vantaggio di un sito statico è che vi va bene un hosting qualsiasi, anche senza database, per cui può andar bene anche quello gratuito di GitHub o GitLab.

Spostatevi nella cartella dove è presente config.toml. A questo punto è importante controllare che l'URL in questo file sia corretto, perché i link generati si baseranno su di esso. Se è tutto a posto si può eseguire zola build.

Il sito compilato si trova nella cartella public, pronto per esser caricato con il vostro programma di fiducia (rsync, scp, ftp...).

Fine. È stato un lungo viaggio, ma ora anche voi siete finalmente pronti a possedere il vostro piccolo angolo di internet, in cui siete voi a fare le regole su ciò che è giusto o non è giusto scrivere. Un piccolo passo per essere più liberi.