Child theme e personalizzazioni: come non perdere le modifiche quando aggiorni WordPress

Come funziona un child theme, come crearlo, cosa cambia con i temi a blocchi e l’Editor del sito, come recuperare le modifiche fatte nel tema principale e dove mettere ogni personalizzazione perché sopravviva agli aggiornamenti di WordPress e di PHP.

Copertina con il logo php∞, la categoria Migrazione CMS, il titolo Child theme e personalizzazioni e il numero 29

Il tema del sito è stato personalizzato anni fa: un colore nel CSS, un campo in più nella pagina del prodotto, un blocco di codice in functions.php per un’integrazione. Le modifiche sono state fatte direttamente nei file del tema, perché era più veloce. Poi arriva la necessità di passare a PHP 8, il tema va aggiornato, e dopo l’aggiornamento il sito ha di nuovo l’aspetto di serie e l’integrazione non funziona più. Le modifiche sono state sovrascritte, e spesso nessuno ha una copia di cosa era stato cambiato.

In questo articolo vediamo come funziona un child theme in WordPress, come crearlo correttamente, cosa cambia con i temi a blocchi e l’Editor del sito, come recuperare le modifiche già fatte nel tema principale e dove mettere ogni tipo di personalizzazione perché sopravviva agli aggiornamenti di WordPress, del tema e di PHP.

Perché le modifiche si perdono

Quando WordPress aggiorna un tema, sostituisce l’intera cartella del tema con quella della nuova versione. Non fa confronti e non conserva i file modificati: tutto ciò che era stato scritto nei file del tema scompare. Lo stesso succede con i plugin. È il comportamento corretto, perché garantisce che il codice installato sia esattamente quello rilasciato dall’autore, con le sue correzioni di sicurezza.

Chi ha modificato il tema principale finisce davanti a una scelta sbagliata in entrambi i casi: aggiornare e perdere le modifiche, oppure non aggiornare e restare con un tema vecchio, che spesso è proprio ciò che impedisce di passare a PHP 8. Il child theme esiste per evitare questa scelta.

Come funziona un child theme

Un child theme, o tema figlio, è un tema che eredita tutto da un altro tema, il tema principale, e contiene solo le differenze. Il manuale dei temi di WordPress descrive le regole, che sono poche:

  • l’unico file obbligatorio è style.css, con le intestazioni standard e il campo Template, che deve corrispondere esattamente al nome della cartella del tema principale;
  • un file di template presente nel tema figlio con lo stesso nome di uno del tema principale lo sostituisce; vale anche per le parti di template e per i pattern, che devono avere lo stesso slug;
  • il functions.php del tema figlio non sostituisce quello del principale: vengono caricati entrambi, prima quello del figlio e subito dopo quello del principale;
  • i file aggiunti nel tema figlio, come nuovi template o fogli di stile, si sommano a quelli del principale.
Schema di come WordPress cerca i file con un child theme attivo. Per un template come single.php, WordPress guarda prima nella cartella del tema figlio e, se non lo trova, in quella del tema principale. Il functions.php del tema figlio viene caricato per primo, poi quello del principale, ed entrambi restano attivi. Per i temi a blocchi gli stili si sommano a livelli, dal basso verso l’alto: theme.json predefinito di WordPress, theme.json del tema principale, theme.json del tema figlio, personalizzazioni dell’utente salvate nel database, che hanno la precedenza su tutto. Una nota indica che l’aggiornamento del tema principale sostituisce solo la sua cartella
Il tema figlio vince sul principale, le personalizzazioni nel database vincono su entrambi.

Una conseguenza importante: non bisogna copiare nel figlio il functions.php del principale. Le funzioni verrebbero dichiarate due volte e il sito si fermerebbe con un errore fatale. Nel figlio si scrive solo il codice nuovo, e per cambiare il comportamento del principale si usano gli hook che mette a disposizione.

Gli strumenti sono tre. I filtri e le azioni del tema principale permettono di cambiare un valore o aggiungere un contenuto senza toccare il suo codice. Un’azione registrata dal principale si toglie con remove_action(), chiamata dal figlio dopo che il principale l’ha aggiunta, di solito sull’hook after_setup_theme. Infine molti temi dichiarano le proprie funzioni dentro un controllo function_exists(): dato che il figlio viene caricato prima, una funzione con lo stesso nome scritta nel figlio prende il posto di quella del principale.

Creare il child theme

Per un tema classico servono due file nella cartella wp-content/themes/. L’esempio usa un tema principale nella cartella temaprincipale: va sostituito con il nome reale.

/* wp-content/themes/temaprincipale-figlio/style.css */
/*
Theme Name: Tema principale, personalizzazioni
Template:   temaprincipale
Version:    1.0.0
*/

<?php
// wp-content/themes/temaprincipale-figlio/functions.php
// Se il tema principale carica solo il foglio di stile del tema attivo,
// carica prima il suo style.css e poi quello del figlio.
add_action( 'wp_enqueue_scripts', function () {
	wp_enqueue_style( 'principale', get_parent_theme_file_uri( 'style.css' ) );
	wp_enqueue_style( 'figlio', get_stylesheet_uri(), array( 'principale' ) );
} );

Molti temi recenti caricano già da soli sia il proprio foglio di stile sia quello del figlio: in quel caso il secondo file può restare vuoto, e il manuale lo indica esplicitamente. Conviene controllare la documentazione del tema principale, perché caricare due volte lo stesso CSS rallenta le pagine. Molti produttori di temi commerciali, inoltre, distribuiscono un child theme già pronto, da usare come punto di partenza.

Temi a blocchi ed Editor del sito

Con i temi a blocchi, come i temi predefiniti da Twenty Twenty-Two in poi, gli stili sono descritti nel file theme.json e si sommano a livelli: quello predefinito di WordPress, quello del tema principale, quello del tema figlio e infine le personalizzazioni fatte dall’utente nell’Editor del sito. Un tema figlio può contenere solo un theme.json con le differenze, senza alcun foglio di stile.

Le personalizzazioni fatte nell’Editor del sito non finiscono nei file del tema: sono salvate nel database e hanno la precedenza su theme.json, template e pattern del tema. Sopravvivono agli aggiornamenti, ma con un effetto collaterale: un template modificato nell’Editor è una copia ferma alla versione del momento, e non riceve più i miglioramenti che il tema principale porta in quel template. Per i siti che contano conviene riportare le modifiche importanti nei file di un tema figlio, sotto controllo di versione, e usare l’Editor per gli aggiustamenti di contenuto.

Recuperare le modifiche già fatte nel tema principale

Se il tema principale è già stato modificato, il primo lavoro è ricostruire cosa è stato cambiato. Il metodo è un confronto tra i file installati e quelli originali della stessa versione, sempre su una copia del sito.

# Versione installata del tema (dal campo Version di style.css)
wp theme get temaprincipale --field=version

# Pacchetto originale della stessa versione: dalla directory di wordpress.org
# per i temi gratuiti, dall'area clienti del produttore per quelli commerciali
mkdir -p /tmp/originale && cd /tmp/originale
curl -sO https://downloads.wordpress.org/theme/temaprincipale.2.3.1.zip
unzip -q temaprincipale.2.3.1.zip

# Elenco dei file modificati o aggiunti, poi il dettaglio delle differenze
diff -rq /tmp/originale/temaprincipale /var/www/sito/wp-content/themes/temaprincipale
diff -ru /tmp/originale/temaprincipale /var/www/sito/wp-content/themes/temaprincipale > modifiche.diff

Il file delle differenze diventa l’elenco di lavoro. Ogni modifica si sposta nel posto giusto: le regole CSS nel style.css del figlio, i template modificati come copie nel figlio, il codice di functions.php nel functions.php del figlio o in un plugin. A quel punto il tema principale si può aggiornare all’ultima versione, e i template copiati nel figlio vanno confrontati con quelli nuovi per riportare le eventuali correzioni dell’autore.

Cosa va nel child theme e cosa no

Il tema figlio è il posto giusto per tutto ciò che riguarda l’aspetto del sito. Le funzioni che devono restare attive anche cambiando tema hanno un posto diverso.

Tabella visiva che associa ogni tipo di personalizzazione al posto in cui metterla. Nel tema figlio: regole CSS, template e parti di template modificati, override dei template di WooCommerce nella cartella woocommerce, theme.json con colori e caratteri. In un plugin di funzionalità: tipi di contenuto e tassonomie, shortcode, integrazioni con gestionali e servizi esterni, modifiche al comportamento di WooCommerce. Nei mu-plugin: regole che devono restare sempre attive e non si possono disattivare dalla bacheca. Nell’Editor del sito o nel Personalizza: piccoli aggiustamenti di contenuto e stile salvati nel database. Mai nei file del tema principale, dei plugin o del core, che gli aggiornamenti sovrascrivono
Aspetto nel tema figlio, funzioni in un plugin, nulla nei file che vengono aggiornati.
  • Nel tema figlio: CSS, template modificati, colori e caratteri in theme.json, e gli override dei template di WooCommerce nella cartella woocommerce del figlio, che vanno riallineati a ogni versione principale come spieghiamo nell’articolo su WooCommerce e PHP 8.
  • In un plugin di funzionalità: tipi di contenuto, tassonomie, shortcode, integrazioni con servizi esterni. Se domani si cambia tema, i contenuti e le integrazioni restano.
  • Nei mu-plugin: i file nella cartella wp-content/mu-plugins vengono caricati sempre e non si possono disattivare dalla bacheca. Sono adatti a regole che non devono mai saltare, come un’impostazione di sicurezza.
  • Mai nei file di terzi: tema principale, plugin e core vengono sostituiti a ogni aggiornamento.

Il codice spostato va anche reso compatibile con PHP 8. Un blocco copiato da un vecchio functions.php può contenere le stesse funzioni rimosse che bloccano i plugin abbandonati, di cui parliamo nell’articolo sui plugin WordPress abbandonati.

Attivare il child theme senza sorprese

WordPress salva alcune impostazioni per singolo tema. Le opzioni del Personalizza, come logo, colori e intestazione, sono memorizzate con il nome del tema attivo, e passando al tema figlio ripartono vuote. Lo stesso può succedere con il CSS aggiuntivo, le posizioni dei menu e i widget. Prima di attivare il figlio in produzione conviene quindi:

  1. attivarlo su una copia del sito e confrontare le pagine principali con quelle originali;
  2. copiare le impostazioni del Personalizza dal tema principale al figlio, per esempio collegando con una pipe wp option get theme_mods_temaprincipale --format=json e wp option update theme_mods_temaprincipale-figlio --format=json, che legge il valore dallo standard input;
  3. riassegnare menu e widget e ricopiare il CSS aggiuntivo, se necessario;
  4. attivare il figlio in produzione in un momento di poco traffico e ricontrollare le pagine.

Da quel momento il tema principale si aggiorna come qualsiasi altro componente, e il percorso verso PHP 8 descritto nell’articolo su WordPress su PHP vecchio non incontra più l’ostacolo delle modifiche da salvare.

Conclusioni

Gli aggiornamenti di WordPress sostituiscono l’intera cartella del tema, quindi le modifiche fatte nei file del tema principale si perdono. Un child theme contiene solo le differenze: un style.css con il campo Template, i template da sostituire e un functions.php che si carica prima di quello del principale senza sostituirlo. Con i temi a blocchi gli stili si sommano a livelli in theme.json, e le modifiche fatte nell’Editor del sito restano nel database come copie ferme nel tempo. Se il tema principale è già stato modificato, un confronto con il pacchetto originale della stessa versione ricostruisce cosa spostare. L’aspetto va nel tema figlio, le funzioni in un plugin o in un mu-plugin, nulla nei file che vengono aggiornati, e prima dell’attivazione vanno copiate le impostazioni salvate per tema.

IL PROSSIMO PASSO

Mettiamo
in sicurezza.

Indicaci versione di PHP, sistema operativo e cosa ti preoccupa. Ti risponderemo con una valutazione dell’esposizione e una proposta di intervento.

Richiedi supporto

Ti porta al modulo di richiesta, in quattro passi.

PHP LEGACY · MANAGED SERVER S.R.L.info@phplegacy.it +39 02 5656 9681

Lunedì – venerdì · 09:30 – 19:30

Urgenza in corso? Reperibilità H24
+39 340 985 4556 ↗