Come ho costruito un archivio strutturato del caso Garlasco con PHP, Google News e schema markup
Quando un caso giudiziario italiano torna sotto i riflettori, le ricerche su Google esplodono per giorni. “Caso garlasco” oggi vale oltre 100.000 ricerche al mese in Italia. Le notizie però sono frammentate su decine di testate: ANSA, Repubblica, Corriere, Sky TG24, Mediaset, AGI, Adnkronos. Chi cerca un quadro d’insieme deve aprire venti tab.
Ho deciso di costruire un sito-archivio che aggregasse tutto in modo strutturato: cronologia, personaggi, prove, processi, news live. Tutto self-hosted, con PHP vanilla, senza CMS, in circa 8 ore di lavoro. Il sito è online a CasoGarlasco.it ed è indicizzato in prima pagina di Google per query competitive entro 24 ore dal lancio.
Questo articolo è il case study tecnico di come l’ho costruito. Niente fluff, solo decisioni architetturali concrete e codice.
La sfida tecnica
Un sito-archivio su un caso giudiziario aperto deve risolvere quattro problemi diversi:
- Aggregare news in tempo reale da decine di fonti, senza scraping abusivo
- Strutturare dati storici (cronologia, personaggi, prove) in modo che siano editabili facilmente
- Performance da prima pagina Google: load time sotto 1.5s, schema markup completo, mobile-first
- Rispetto legale assoluto: presunzione di innocenza, attribuzione delle fonti, niente diffamazione
Quattro problemi che, presi insieme, scoraggerebbero la maggior parte degli sviluppatori dal partire. Vediamo come li ho affrontati.
Stack tecnico (volutamente minimale)
- HTML/CSS/JS vanilla per il frontend (zero framework)
- PHP 8 per i due endpoint server (news proxy + scanner)
- JSON come database (un singolo
data.jsonaggiornato a mano) - Leaflet.js per la mappa interattiva
- OpenStreetMap + CartoDB Dark per i tile mappa (gratis, dark mode)
- Google Fonts: Fraunces + JetBrains Mono + Inter
- Cloudflare Web Analytics (cookieless, no banner cookie)
Nessuna dipendenza npm. Nessun framework. Nessun database. Tutto deploy via FTP. Il sito intero pesa meno di 100 KB caricato.
Questa scelta non è nostalgica: è strategica. Meno dipendenze = meno breakage, e per un progetto solitario che voglio mantenere per anni, ogni dipendenza è un debito tecnico futuro. PHP 8 è installato su ogni hosting low-cost, Leaflet è stabile da una decade, e i JSON sono editabili con qualsiasi editor.
Architettura: due endpoint, un file dati, un frontend
Il sito è una single-page application con dieci sezioni navigabili tramite anchor link. Tutta la logica server è in due file PHP da poche centinaia di righe ciascuno:
news.php — Il proxy Google News
Google News offre un feed RSS pubblico ma per query specifiche. Il problema è che chiamarlo direttamente dal browser viene bloccato da CORS, e i servizi pubblici di aggregazione (rss2json, AllOrigins) hanno rate limit aggressivi.
La soluzione: un proxy PHP che fa la richiesta server-side, parsa il feed con simplexml, cacha il risultato per 10 minuti su filesystem, e serve un JSON pulito al frontend.
php
$query = '(garlasco OR "Andrea Sempio" OR "Chiara Poggi" OR "Alberto Stasi" OR "Mario Venditti")';
$url = 'https://news.google.com/rss/search?' . http_build_query([
'q' => $query,
'hl' => 'it',
'gl' => 'IT',
'ceid' => 'IT:it',
]);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 15,
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; CasoGarlascoBot/1.0)',
]);
$xml = curl_exec($ch);
Il cache filesystem (news-cache.json) è semplice e robusto: se la modifica è recente meno di 10 minuti, servo quel file. Altrimenti faccio una nuova chiamata e aggiorno il file con rename atomico per evitare race condition.
Risultato: il frontend chiama news.php ogni 5 minuti dal browser. Google News viene contattato al massimo 6 volte all’ora (ogni 10 minuti di cache). Sostenibile per qualsiasi hosting low-cost.
update.php — Lo scanner intelligente
Qui c’è la parte interessante. Lo scanner ogni 2 ore (via cron) prende i 30 articoli più recenti, e per ognuno:
- Estrae le persone tracciate (Andrea Sempio, Alberto Stasi, Mario Venditti, ecc.) tramite pattern matching sul titolo + description
- Estrae gli eventi giudiziari (udienza, sentenza, perquisizione, perizia, revisione, ecc.)
- Categorizza la news in
processo,indagine,perizie,corruzione,famiglia,intercettazioni - Deduplica confrontando con l’archivio esistente
- Scrive in
news-archive.jsonun payload arricchito (titolo, fonte, data, link, persone, eventi, categoria)
Il regex per le persone è case-insensitive e cerca varianti:
php
$peopleMap = [
'andrea sempio' => 'Andrea Sempio',
'alberto stasi' => 'Alberto Stasi',
'mario venditti' => 'Mario Venditti',
// ...
];
foreach ($peopleMap as $key => $name) {
if (strpos($full, $key) !== false) {
$foundPeople[$name] = true;
}
}
La categorizzazione automatica usa pattern di parole chiave:
php
function categorize($text) {
$t = strtolower($text);
if (preg_match('/\b(sentenza|condanna|cassazione|revisione)\b/u', $t)) return 'processo';
if (preg_match('/\b(dna|impronta|perizia|consulenza)\b/u', $t)) return 'perizie';
if (preg_match('/\b(interrogator|indagat|perquisizion)\b/u', $t)) return 'indagine';
// ...
return 'cronaca';
}
Lezione importante: lo scanner non aggiorna mai automaticamente data.json (la cronologia ufficiale del sito). Su un caso giudiziario aperto, ogni affermazione del sito è un potenziale rischio diffamazione. Lo scanner suggerisce in incoming.json, ma le decisioni editoriali restano umane. Solo la rassegna stampa (news-archive.json) è automatica, perché è rassegna pura: titolo + link alla fonte originale.
Il problema legale (e perché è una feature)
Un sito su un caso giudiziario in corso è un campo minato:
- Diffamazione: Sempio è indagato, non condannato. Ogni affermazione che lo collega all’omicidio in modo non-attribuito è rischio causa civile + penale
- Segreto istruttorio: leak di atti riservati possono configurare reato
- Diritto d’autore: foto, video, audio da TV/giornali sono protetti
- Privacy: la famiglia della vittima ha fatto causa a testate per uso non autorizzato di foto
Ho risolto con tre regole rigide impostate dall’inizio:
- Mai foto delle persone coinvolte. Solo SVG illustrativi e avatar generati con le iniziali del nome. Zero rischio copyright, zero rischio privacy
- Mai affermazioni dirette. Ogni voce della cronologia ha un campo
fonti[]obbligatorio con almeno un link verificabile. Ogni card news mostra esplicitamente “Sky TG24 / 12 maggio 2026” - Banner disclaimer permanente in cima a ogni pagina: “Presunzione di innocenza per tutti gli indagati”
Queste regole non sono burocrazia: sono protezione attiva. Un avvocato che valuta una causa diffamazione contro un sito vede questi elementi e quasi sempre rinuncia. La probabilità di vincere contro un sito che “non afferma” ma “riporta” è bassa.
Performance SEO: cosa premia Google
Il sito è online da 24 ore mentre scrivo questo articolo. Search Console mostra 49 impressioni sulle prime 24 ore, con posizione media 7.86 su query competitive tipo “caso garlasco” e “delitto garlasco” (posizione 5 in prima pagina). Per un dominio nuovo in tema YMHL, è risultato eccezionale.
Quattro elementi tecnici che hanno fatto la differenza:
1. Schema markup completo
Tre tipi di schema annidati in un singolo <script type="application/ld+json">:
- WebSite: nome, URL, lingua, descrizione
- NewsArticle: titolo, data pubblicazione, autore, publisher
- FAQPage: 6 domande FAQ con risposte (le query più cercate su Google)
Lo schema FAQPage è particolarmente potente: Google mostra le risposte direttamente in SERP come rich snippet, aumentando il CTR del 10-20%.
2. Title e meta description ottimizzati per intent
html
<title>Caso Garlasco: cronologia, indagati e prove in tempo reale | CasoGarlasco.it</title>
<meta name="description" content="Caso Garlasco: cronologia completa dal 2007, indagati attuali (Andrea Sempio, Mario Venditti, Giuseppe Sempio), prove (DNA, impronta 33, scontrino Vigevano), tutti i gradi di giudizio. Aggiornato in tempo reale, solo fonti verificate." />
Il title contiene il keyword principale all’inizio, poi due keyword secondarie (“cronologia”, “indagati”). La meta description elenca tutti i nomi rilevanti (Google li usa per il ranking) e termina con un value proposition (“solo fonti verificate”).
3. Mobile-first responsive con dark mode
Lo stile usa CSS variables, dark mode di default, tipografia serif elegante (Fraunces) per i titoli + mono (JetBrains) per i terminali “in stile retrocomputing”. Tre media query gestiscono il responsive: 880px, 640px, e default.
Google Lighthouse Mobile: 96 su Performance, 100 su SEO, 100 su Accessibility.
4. Aggiornamento contenuto continuo
Il cron che gira ogni 2 ore aggiorna news-archive.json con nuove news. Anche se il sito è single-page e i contenuti principali (cronologia, personaggi) cambiano poco, Google vede che /news-archive.json cambia continuamente, e interpreta il sito come “attivo”.
L’idea che Google premi i siti con contenuto fresh è vera, ma con un caveat: il contenuto fresh deve essere rilevante e non spam. Una rassegna stampa categorizzata e taggata è rilevante. Un’auto-generazione di articoli AI sarebbe spam e verrebbe penalizzata.
I dettagli che fanno la differenza
Tre piccole scelte che hanno avuto impatto sproporzionato:
- Banner disclaimer in cima (sopra l’header): segnale di seriosità sia agli utenti che a Google
- Tag colorati per persona/evento nelle card news (chip ambra per persone, cyan per eventi): aumenta engagement e tempo sulla pagina
- Filtri categoria in alto alla sezione news: trasforma il sito da aggregatore passivo a strumento di consultazione
Quest’ultimo è il “value add” che Google cerca quando valuta un aggregatore. Non bastano i link, serve l’organizzazione.
Cosa farei diversamente
Tre cose che cambierò nelle prossime settimane:
- Pagine dettaglio per ogni persona: ora i personaggi sono card in una grid. Diventare pagine standalone con URL canonici (
/personaggi/andrea-sempio/) sbloccherebbe ranking individuale per ogni query “chi è X” - BreadcrumbList schema: già pianificato, aggiungerò navigazione strutturata in JSON-LD
- Newsletter con pacchetto settimanale automatico: opt-in nativo, valore aggiuntivo per gli utenti, fonte di traffico ricorrente
Conclusioni: il vero ROI del minimal stack
Otto ore di lavoro. Zero costi fissi mensili (hosting a 30€/anno, dominio a 10€/anno). Niente CMS da aggiornare, niente plugin che si rompono, niente dipendenze npm da auditare. Il sito sopravvive a chiunque lo costruisca, perché chiunque sa leggere HTML e PHP.
Negli ultimi anni il discorso pubblico SEO si è spostato su tool complessi (headless CMS, frameworks edge, generative AI). La verità però è che la maggior parte dei siti piccoli/medi non ha bisogno di nulla di tutto ciò. Un PHP onesto, un JSON ben strutturato, un CSS curato, e schema markup completo battono regolarmente stack moderni mal configurati.
Il caso Garlasco è un esempio concreto di SEO tecnico ben fatto. Se vuoi vedere il progetto live, è a CasoGarlasco.it. Tutti i pattern descritti in questo articolo sono replicabili su qualsiasi tema verticale: un caso giudiziario, un trend di cronaca, un evento sportivo, una crisi sanitaria, una serie TV in corso.
L’opportunità c’è sempre: il problema è solo il tempo di esecuzione.





