Il functions.php è uno dei principali file di WordPress ed aiuta a gestire e aumentare le funzionalità dell’intera piattaforma.
Ogni tema ha il suo file functions.php, che si trova nella cartella principale dello stesso e che viene utilizzato per gestire le funzioni personalizzate o per modificare il comportamento del tema in uso.
A differenza di un plugin che funziona in modo “indipendente”, tutte le personalizzazioni fatte su uno specifico functions.php agiranno solo su uno specifico tema.
Un child theme può avere un proprio file functions.php e le sue funzionalità verranno utilizzate per incrementare o sostituire le features del tema principale.
Questa è la modalità di sviluppo più consigliata dato che permette una gestione sicura e separata dal tema originale che potrà essere aggiornato.
Si possono fare innumerevoli personalizzazioni attraverso questo file, qui di seguito saranno elencate alcune tra le più utili.
Aggiungere o abilitare
Aggiungere CSS o JavaScript esterni
Questo hook permette di inserire chiamate a risorse esterne per integrare fogli stile o plugin JavaScript.
La funzione wp_enqueue_style
importa CSS esterni.
function addThemeScripts() {
wp_enqueue_style( 'new-style', get_stylesheet_directory_uri() . '/css/new-style.css', array(), '', 'all' );
}
add_action( 'wp_enqueue_scripts', 'addThemeScripts' );
La funzione wp_enqueue_script
importa JavaScript esterni.
function addThemeScripts() {
wp_enqueue_script( 'new-script', get_stylesheet_directory_uri() . '/js/new-script.js', array(), '', true );
}
add_action( 'wp_enqueue_scripts', 'addThemeScripts' );
Ogni parametro, in un preciso ordine e delimitato dalla virgola, imposta una specifica stringa:
- $handle è l’identificativo che verrà associato al file (nel caso di CSS verrà attribuito un
id
composto dal nome il suffisso-css
, es.new-style-css
- $src è il percorso che se preceduto da
get_stylesheet_directory_uri()
non necessità dell’intero path per raggiungere la cartella principale del tema - $deps indica eventuali dipendenze da altri file, usato se ad esempio per far si che un codice JS non scatti prima della libreria jQuery (es.
array('jquery')
) - $ver specifica l’eventuale versione del file appendendo una stringa al nome del file
/new-script.js?ver=4.8.2
(se lasciato vuoto utilizzerà la versione di WordPress installata)
L’ultimo parametro a seconda del tipo di risorsa è differente:
- $media per i CSS e viene utilizzato per specificare il tipo di media (es.
media="screen"
- $in_footer per i JavaScript indica se la risorsa deve essere posizionata nell’intestazione (
false
) o nel footer (true
)
Il risultato finale (ovvero la porzione di HTML aggiunta nel codice) sarà a seconda dei parametri, più o meno il seguente.
<!-- CSS -->
<script type="text/javascript" src="https://domain.com/wp-content/themes/mytheme/js/new-script.js?ver=4.8.2"></script>
<!-- JavaScript -->
<link rel="stylesheet" id="new-style-css" href="https://domain.com/wp-content/themes/mytheme/css/new-style.css?ver=4.8.2" type="text/css" media="all" />
Inserire codice nella testata <head>
Per aggiungere codice o integrare CSS/JavaScript nella testata senza manipolare il tema.
function add_codeToHead() {
$code = '<style rel="stylesheet" type="text/css" src="/css/style.css" media="all" />';
echo $code;
}
add_action('wp_head', 'add_codeToHead', 1);
Il valore 1
definisce la priorità (espressa in una scala da 1 a 10). Con 1
, massima priorità, il codice sarà inserito più in alto possibile appena dopo l’apertura del tag <head>
.
Con 10
, minima priorità, sarà inserito appena prima della chiusura del tag </head>
.
Inserire codice nel footer
Per aggiungere codice o integrare CSS/JavaScript nel footer senza manipolare il tema.
function add_codeToFooter() {
$code = '<script type="text/javascript" src="/js/library.js"></script>';
echo $code;
}
add_action('wp_footer', 'add_codeToFooter');
Consentire l’upload di qualsiasi file
Per impostazione predefinita, WordPress permette di caricare pochi tipi di file (tipicamente quelli multimediali comuni come .png e .jpg). È però possibile estendere la possibilità di upload a qualsiasi tipo di file.
function my_myme_types($mime_types){
$mime_types['svg'] = 'image/svg+xml'; // Consenti di caricare SVG
$mime_types['psd'] = 'image/vnd.adobe.photoshop'; // Consenti di caricare PSD
return $mime_types;
}
add_filter('upload_mimes', 'my_myme_types', 1, 1);
In questa pagina è disponibile una lista completa di tutte le tipologie di MIME types / Internet Media Types per creare una funzione ad hoc.
Rimuovere o escludere
Rimuovere l’ID quando si richiamano fogli stile
Identifica tutte le chiamate CSS che hanno un ID che contiene “-css
” e rimuove l’attributo id
.
function remove_style_id($link) {
return preg_replace("/id='.*-css'/", "", $link);
}
add_filter('style_loader_tag', 'remove_style_id');
- Codice iniziale
<link rel="stylesheet" id="cssName-css" href="/css/styles.css" type="text/css" media="all" />
- Risultato (senza ID)
<link rel="stylesheet" href="/css/styles.css" type="text/css" media="all" />
Disabilitare Gutenberg editor
Dalla versione di WordPress 5.0 è presente Gutenberg ed è possibile disabilitare il suo funzionamento senza utilizzare plugin.
add_filter( 'use_block_editor_for_post', '__return_false' );
Questo comando si aggancia al filtro use_block_editor_for_post
per limitare l’attivazione di Gutenberg durante la scrittura attraverso la funzione di WordPress __return_false
.
Rimuovere script e stili Emoji
WordPress 4.2 ha aggiunto il supporto alle Emoji e se non si ha necessità di utilizzarle è meglio rimuoverle per ottenere prestazioni migliori (meno JavaScript e CSS).
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
remove_action( 'admin_print_styles', 'print_emoji_styles' );
Cosa verrà eliminato? Saranno rimosse tutte queste stringhe di codice presenti nell’output HTML.
<script type="text/javascript">
window._wpemojiSettings = {"baseUrl":"https:\/\/s.w.org\/images\/core\/emoji\/2.3\/72x72\/","ext":".png","svgUrl":"https:\/\/s.w.org\/images\/core\/emoji\/2.3\/svg\/","svgExt":".svg","source":{"concatemoji":"http:\/\/domainname.com\/wp-includes\/js\/wp-emoji-release.min.js?ver=4.8.2"}};
!function(a,b,c){function d(a){var b,c,d,e,f=String.fromCharCode;if(!k||!k.fillText)return!1;switch(k.clearRect(0,0,j.width,j.height),k.textBaseline="top",k.font="600 32px Arial",a){case"flag":return k.fillText(f(55356,56826,55356,56819),0,0),b=j.toDataURL(),k.clearRect(0,0,j.width,j.height),k.fillText(f(55356,56826,8203,55356,56819),0,0),c=j.toDataURL(),b!==c&&(k.clearRect(0,0,j.width,j.height),k.fillText(f(55356,57332,56128,56423,56128,56418,56128,56421,56128,56430,56128,56423,56128,56447),0,0),b=j.toDataURL(),k.clearRect(0,0,j.width,j.height),k.fillText(f(55356,57332,8203,56128,56423,8203,56128,56418,8203,56128,56421,8203,56128,56430,8203,56128,56423,8203,56128,56447),0,0),c=j.toDataURL(),b!==c);case"emoji4":return k.fillText(f(55358,56794,8205,9794,65039),0,0),d=j.toDataURL(),k.clearRect(0,0,j.width,j.height),k.fillText(f(55358,56794,8203,9794,65039),0,0),e=j.toDataURL(),d!==e}return!1}function e(a){var c=b.createElement("script");c.src=a,c.defer=c.type="text/javascript",b.getElementsByTagName("head")[0].appendChild(c)}var f,g,h,i,j=b.createElement("canvas"),k=j.getContext&&j.getContext("2d");for(i=Array("flag","emoji4"),c.supports={everything:!0,everythingExceptFlag:!0},h=0;h<i.length;h++)c.supports[i[h]]=d(i[h]),c.supports.everything=c.supports.everything&&c.supports[i[h]],"flag"!==i[h]&&(c.supports.everythingExceptFlag=c.supports.everythingExceptFlag&&c.supports[i[h]]);c.supports.everythingExceptFlag=c.supports.everythingExceptFlag&&!c.supports.flag,c.DOMReady=!1,c.readyCallback=function(){c.DOMReady=!0},c.supports.everything||(g=function(){c.readyCallback()},b.addEventListener?(b.addEventListener("DOMContentLoaded",g,!1),a.addEventListener("load",g,!1)):(a.attachEvent("onload",g),b.attachEvent("onreadystatechange",function(){"complete"===b.readyState&&c.readyCallback()})),f=c.source||{},f.concatemoji?e(f.concatemoji):f.wpemoji&&f.twemoji&&(e(f.twemoji),e(f.wpemoji)))}(window,document,window._wpemojiSettings);
</script>
<style type="text/css">
img.wp-smiley,
img.emoji {
display: inline !important;
border: none !important;
box-shadow: none !important;
height: 1em !important;
width: 1em !important;
margin: 0 .07em !important;
vertical-align: -0.1em !important;
background: none !important;
padding: 0 !important;
}
</style>
Disattivare la ricerca
Se si desidera disattivare completamente la funzionalità di ricerca su sito questa funzione viene in aiuto: è sconsigliato inibirla dato che è uno strumento di estremo aiuto all’usabilità ma in alcuni contesti può essere necessario (come ad esempio su delle “one page” senza ulteriori livelli di navigazione).
function fb_filter_query( $query, $error = true ) {
if ( is_search() ) {
$query->is_search = false;
$query->query_vars[s] = false;
$query->query[s] = false;
if ( $error == true )
$query->is_404 = true;
}
}
add_action( 'parse_query', 'fb_filter_query' );
add_filter( 'get_search_form', create_function( '$a', "return null;" ) );
In questo modo i risultati di una ricerca rimanderanno ad una schermata di errore utilizzando il template delle pagine 404.
Escludere pagine dalla ricerca
Per limitare la ricerca solo agli articoli evitando che tra i risultati vengano mostrate anche le pagine.
if ($query->is_search) {
$query->set('post_type', 'post');
}
return $query;
}
add_filter('pre_get_posts','SearchFilter');
Disabilitare i feed RSS
Sebbene sia una grande funzionalità di WordPress, se non sia ha intenzione di sfruttare i feed RSS, essi possono essere disattivati completamente.
function itsme_disable_feed() {
wp_die( __('Nessun feed disponibile, visita la <a href="'. get_bloginfo('url') .'">homepage</a>!') );
}
add_action('do_feed', 'itsme_disable_feed', 1);
add_action('do_feed_rdf', 'itsme_disable_feed', 1);
add_action('do_feed_rss', 'itsme_disable_feed', 1);
add_action('do_feed_rss2', 'itsme_disable_feed', 1);
add_action('do_feed_atom', 'itsme_disable_feed', 1);
add_action('do_feed_rss2_comments', 'itsme_disable_feed', 1);
add_action('do_feed_atom_comments', 'itsme_disable_feed', 1);
Con la funzione wp_die
è possibile inserire un messaggio personalizzato che in questo caso avvisa della mancanza del feed RSS e rimanda alla homepage.
Se una persona visiterà la pagina di un feed RSS sul sito, ad esempio example.com/feed, vedrà il seguente messaggio.

Minificare il codice della pagina
Un codice sorgente minificato permette di ottenere un peso minore del tema e un rendering più efficiente.
Con un sistema di sostituzione automatica è possibile gestire una completa rimozione degli spazi bianchi superflui e dei commenti ottenendo un codice compresso e privo di formattazione.
function sanitize_output($buffer) {
$search = array(
'/\>[^\S ]+/s', // Rimozione spazi bianchi dopo i tag
'/[^\S ]+\</s', // Rimozione spazi bianchi prima dei tag
'/(\s)+/s', // Rimozione sequenze multiple di spazi bianchi
'/<!--(.|\s)*?-->/' // Rimozione commenti HTML
);
$replace = array(
'>',
'<',
'\\1',
''
);
$buffer = preg_replace($search, $replace, $buffer);
return $buffer;
}
ob_start("sanitize_output");
Plugin come Autoptimize offrono un sistema completo e selettivo per la gestione e la compressione del codice HTML, CSS e JavaScript.
Cambiare o identificare
Aggiornare l’indirizzo del sito
Se il dominio è cambiato o più semplicemente si passa da un protocollo http a https la pagina di accesso a WordPress potrebbe non essere più raggiungibile dato che nel database è memorizzato il “vecchio” URL.
Il modo più semplice per comunicare a WordPress il nuovo indirizzo è quello di aggiungere questo codice al fie functions.php.
update_option( 'siteurl', 'https://example.com' );
update_option( 'home', 'https://example.com' );
Una volta effettuato il primo accesso sarà possibile puoi andare sulle impostazioni e impostare il nuovo dominio rimuovendo la funzione non più necessaria.
Riscrivere gli slug principali
Per cambiare gli slug di base (ovvero quella parte di URL che definisce un’area del sito come /page/ nel caso delle paginazione) o semplicemente per tradurli.
function re_rewrite_rules() {
global $wp_rewrite;
$wp_rewrite->author_base = 'autore';
$wp_rewrite->search_base = 'ricerca';
$wp_rewrite->comments_base = 'commento';
$wp_rewrite->pagination_base = 'pagina';
$wp_rewrite->flush_rules();
}
add_action('init', 're_rewrite_rules');
In questo modo l’URL cambierà, ad esempio nel caso ci sia una paginazione, da /page/2/
a /pagina/2/
.
Individuare una pagina o un articolo
Talvolta può essere necessario richiamare alcune librerie o porzioni di codice solo per determinate pagine o post: attraverso l’ID del contenuto è possibile utilizzare un condizione specifica che andrà ad agire solo su quella risorsa specifica.
Per identificare l’ID (un numero univoco che etichetta la pagina stessa) basta aprire dalla gestione di WordPress l’interfaccia di modifica e verificare l’URL: nel caso, ad esempio, di questo articolo l’URL è /post.php?post=839&action=edit
e di conseguenza l’ID è 839
.
// Identifica una pagina
if ( is_page(345) ) {
// Esegui questo script o questa funzione
}
// Identifica un Articolo/post
if ( is_single(678) ) {
// Esegui questo script o questa funzione
}
È anche possibile identificare più pagine e articoli utilizzando un semplice array.
// Identifica più pagine
if ( is_page( array(1849, 728) ) ) {
// Esegui questo script o questa funzione
}
// Identifica più Articoli/post
if ( is_single( array(249, 1723) ) ) {
// Esegui questo script o questa funzione
}
Identificare gli utenti loggati
Questa condizione permettere di caricare o inibire l’utilizzo di script o codice nel momento in cui un utente è ha effettuato l’accesso a WordPress.
// Se l'utente è loggato
if ( is_user_logged_in() ) {
// Esegui questo script o questa funzione
}
// Se l'utente non è loggato
if ( !is_user_logged_in() ) {
// Esegui questo script o questa funzione
}
Può essere molto comodo ad esempio per escludere il tracciamento del proprio traffico su Analytics (o quello dei proprio collaboratori) o per evitare il richiamo di qualsiasi altro script (advertising, profilazione, remarketing, social, ecc…) per tutti gli utenti che gestiscono il sito.
Modificare l’email sender
Quando si utilizzando alcuni plugin o servizi che prevedono l’invio in modo automatico di email, WordPress utilizzata rispettivamente come email sender wordpress@example.com e come name sender WordPress (dove example.com corrisponde all’indirizzo del sito).
Per cambiare questi valori è possibile utilizzare una funzione che va a sovrascrivere quelli di default consentendo di personalizzare l’email.
// Cambio indirizzo email del mittente
function wpb_sender_email( $original_email_address ) {
return 'email@example.comt';
}
// Cambio il nome del mittente
function wpb_sender_name( $original_email_from ) {
return 'Il mio Sito Web';
}
// Applico le regole per sovrascrivere quelle di WordPress
add_filter( 'wp_mail_from', 'wpb_sender_email' );
add_filter( 'wp_mail_from_name', 'wpb_sender_name' );
Personalizzazioni avanzate
Sfruttando tutte le potenzialità di questo file è possibile replicare praticamente qualsiasi funzionalità sostituendo l’utilizzo di plugin invasivi che spesso vengono utilizzati solo per alcuni utilizzi limitati.
Altre cose che si possono fare conoscendo il functions.php? Ecco alcuni esempi.
Ciao Nicholas, complimenti vivissimi per l’articolo. Penso che sia molto utile per tantissime persone che come me, vanno alla ricerca sempre di quel qualcosa di particolare per migliorare se stessi e il proprio sito.
Ne approfitto per chiederti una cosa.
Ho un blog multiautore dove tanti contenuti vengono inseriti dagli utenti iscritti e vorrei implementare via codice il rel “ugc” ai link. Immagino che dal functions.php sia possibile. Sapresti aiutarmi per favore?
Grazie
Ciao Paolo,
Google ha recentemente annunciato che il valore “ugc” è supportato per i contenuti generati dagli utenti e infatti a partire dalla versione WordPress 5.3, i collegamenti nei commenti e negli URL usano l’attributo
rel = "nofollow ugc"
per impostazione predefinita.Quindi ti consiglio semplicemente di aggiornare la tua versione di WordPress senza ricorrere a soluzioni alternative.
Si Nicholas lo sapevo. Io invece vorrei metterlo di default nel corpo degli articoli scritti dagli utenti. Penso sia questa la vera natura dell’ugc, oltre che nei commenti.
Sicuramente una soluzione “pratica” potrebbe essere quella di modificare lato JavaScript i tag interessati solo per quei tipi di contenuto.
Altrimenti devi capire come manipolare con il functions.php il codice ma non c’è una regola generale per una cosa così specifica.
Ciao Nicholas,
sono alle prime armi nello sfruttare il file functions.php.
Avrei bisogno di poter nascondere un elemento quando un utente non è loggato.
ho creato questa classe
.classe-da-nascondere {
display: none;
}
…mi spieghi come aggiungere la condizione (not) logged_in?
grazie mille
Puoi semplicemente inserire all’interno del controllo PHP una funzione
echo
per “stampare” nel codice la tua condizione:Questo però non ti permette di posizionare correttamente la stringa quindi io userei l’approccio descritto qui: Aggiungere CSS o JavaScript esterni.