selovuoisapere.it è una raccolta di pubblicazioni — dossier, report e relazioni ministeriali — sul tema delle violenze e dei maltrattamenti sui minori. L'obiettivo è rendere accessibili dati e documenti che spesso non sono di facile reperibilità, per supportare giornalisti, studenti, ricercatori, genitori e educatori.
- Raccogliere in un unico posto le principali pubblicazioni istituzionali e di terzo settore sui maltrattamenti sui minori in Italia e nel mondo
- Catalogare ogni pubblicazione per tipo di violenza (fisica, psicologica, sessuale, negligenza, sfruttamento, ecc.) per facilitarne la ricerca
- Presentare per ogni documento un dato significativo e una descrizione sintetica, così da orientare chi cerca informazioni senza dover scaricare ogni PDF
Il sito è composto da quattro sezioni:
- Home — presentazione della missione
- Pubblicazioni — griglia filtrabile di tutte le pubblicazioni, ordinata per data decrescente
- Chi sono — informazioni sulla curatrice e contatti per suggerire nuove pubblicazioni
- About — note tecniche sul progetto
Ogni scheda pubblicazione contiene: fonte, tipo/i di violenza, un dato significativo in evidenza, una descrizione del contenuto, e il link al PDF originale.
Tutta la gestione dei contenuti è centralizzata in un unico file CSV. Da lì, due script generano i file del sito e le copertine.
flowchart TD
CSV["📄 script/risorse/lista-pubblicazioni.csv\n(fonte unica di tutti i metadati)"]
subgraph lista["script/lista.sh"]
L1["mlrgo → filtra pronto=x\njq → estrae campi\nqsv safenames → normalizza filename"]
end
subgraph pdf["script/pdf-download-cover.sh"]
P1["curl → scarica PDF"]
P2["pdftoppm → estrae prima pagina PNG"]
P3["convert → ridimensiona a 640×480"]
P1 --> P2 --> P3
end
subgraph output["Output per ogni pubblicazione (pubblicazioni/{id}/)"]
QMD["{filename}.qmd\n(frontmatter: titolo, data, fonte,\ncategorie, social card)"]
INC["include/_{id}.qmd\n(corpo: fonte, dato significativo,\ndescrizione, link PDF, immagine)"]
PNG["{filename}_resized.png\n(copertina)"]
end
BUILD["quarto render\n→ docs/ (GitHub Pages)"]
CSV --> lista --> QMD & INC
CSV --> pdf --> PNG
QMD & INC & PNG --> BUILD
Note importanti:
pubblicazioni/01/include/_01.qmdè l'unico file gestito manualmente: lo script lo ripristina congit checkoutalla fine di ogni esecuzione, preservando le modifiche manuali- I PDF vengono scaricati solo se non già presenti (
-d sìforza il re-download e rigenera tutto) - Il campo
pronto="x"nel CSV controlla quali pubblicazioni vengono pubblicate
Contribuire significa aggiungere o aggiornare pubblicazioni. In sintesi:
- Si modifica il file CSV in
script/risorse/lista-pubblicazioni.csv - Si prepara manualmente la copertina PNG nella cartella della pubblicazione
- Si esegue
script/lista.pyper generare i file del sito - Si fa il build con
quarto render
Ogni pubblicazione ha una cartella numerata dentro pubblicazioni/:
script/
└── risorse/
└── lista-pubblicazioni.csv ← fonte unica di tutti i metadati
pubblicazioni/
├── 01/ ← id della pubblicazione
│ ├── indifesa-2023.qmd ← file generato da lista.py (frontmatter)
│ ├── indifesa-2023_resized.png← copertina (copiata da risorse/)
│ ├── include/
│ │ └── _01.qmd ← contenuto della pagina (generato, eccetto pub. 01)
│ └── risorse/
│ └── indifesa-2023_resized.png ← copertina da preparare manualmente
├── 02/
│ └── ...
└── index.qmd ← listing grid (non toccare)
L'id è un numero progressivo a due cifre (01, 02, …) che identifica la pubblicazione. Viene dalla colonna id del CSV e determina il nome della cartella.
Il {filename} è lo slug della pubblicazione: lista.py prende la colonna titolo dal CSV e la normalizza — minuscolo, caratteri speciali sostituiti da -, troncato a 60 caratteri. Diventa il nome del file .qmd e la parte finale dell'URL della pagina.
Esempio:
titolo = "Indifesa 2023"→filename = indifesa-2023→ URL:/pubblicazioni/01/indifesa-2023.html
Tutto parte da script/risorse/lista-pubblicazioni.csv. Ogni riga è una pubblicazione. Le colonne rilevanti sono:
| Colonna | Descrizione |
|---|---|
id |
numero progressivo, determina la cartella |
titolo |
titolo della pubblicazione |
pronto |
x = pubblicata, vuoto = nascosta |
fonte |
ente che ha prodotto il documento |
anno-mese |
data nel formato YYYY-MM (es. 2023-09) |
violenze |
categorie separate da virgola (es. fisica, sessuale) |
data-claim |
dato statistico significativo da mettere in evidenza |
descrizione |
testo descrittivo della pubblicazione |
URL |
link diretto al PDF |
flowchart TD
CSV["📄 script/risorse/lista-pubblicazioni.csv\n(fonte unica di tutti i metadati)"]
IMG["🖼 pubblicazioni/{id}/risorse/{filename}_resized.png\n(copertina preparata manualmente)"]
subgraph lista["script/lista.py (Python ≥ 3.11, uv)"]
L1["legge CSV → filtra pronto=x\nnormalizza filename e campi\ncopia copertina se presente"]
end
subgraph output["Output per ogni pubblicazione (pubblicazioni/{id}/)"]
QMD["{filename}.qmd\n(frontmatter: titolo, data, fonte,\ncategorie, social card)"]
INC["include/_{id}.qmd\n(corpo: fonte, dato significativo,\ndescrizione, link PDF, immagine)"]
end
BUILD["quarto render → docs/ (GitHub Pages)"]
CSV --> lista --> QMD & INC
IMG --> lista
QMD & INC --> BUILD
Come eseguire:
# Genera i .qmd dal CSV
uv run --project script python script/lista.py
# Build del sito
quarto renderLo script usa solo la libreria standard di Python (≥ 3.11) e non ha dipendenze esterne. uv non è obbligatorio — si può lanciare anche con python3 script/lista.py direttamente — ma con uv run l'ambiente viene configurato automaticamente senza dover fare nulla.
Ogni pubblicazione può avere una copertina che appare nella griglia e nella pagina del documento.
Posizione: pubblicazioni/{id}/risorse/{filename}_resized.png
Come si determina {filename}: è la normalizzazione del campo titolo nel CSV — tutto minuscolo, caratteri non alfanumerici sostituiti da -, troncato a 60 caratteri. Ad esempio:
titolo nel CSV |
{filename} |
|---|---|
Indifesa 2023 |
indifesa-2023 |
L'abuso sessuale online in danno di minori |
l-abuso-sessuale-online-in-danno-di-minori |
Formato: PNG, 790×480 px, sfondo bianco.
Quando si esegue lista.py, se il file {filename}_resized.png è presente nella cartella risorse/, viene copiato automaticamente nella directory della pubblicazione e referenziato nel frontmatter e nelle social card.
Una volta preparati i contenuti (CSV aggiornato e copertine nella cartella risorse/), basta fare commit e push su main. Il sito si aggiorna da solo.
Il repository usa GitHub Actions per automatizzare l'intero processo: generazione dei file, build del sito e deploy. Non serve fare nulla manualmente dopo il push.
Il workflow parte automaticamente quando cambiano:
script/risorse/lista-pubblicazioni.csv- file dentro
pubblicazioni/ - file dentro
immagini/ - file
.qmd,.scss,_quarto.yml
- Aggiorna il CSV — modifica
script/risorse/lista-pubblicazioni.csvcon i nuovi metadati (o impostapronto=xper attivare una pubblicazione) - Prepara la copertina — salva il PNG in
pubblicazioni/{id}/risorse/{filename}_resized.png(790×480 px, sfondo bianco) - Fai commit e push su
main
git add script/risorse/lista-pubblicazioni.csv pubblicazioni/
git commit -m "aggiungi pubblicazione XY"
git push- Attendi ~1 minuto — GitHub Actions genera i
.qmd, fa il render e pubblica su GitHub Pages automaticamente
Non è necessario eseguire
lista.pyoquarto renderin locale prima del push: ci pensa il workflow.