Skip to content
⚡ Come aggiungere il tuo shortcode in WordPress: esempi e codice

⚡ Come aggiungere il tuo shortcode in WordPress: esempi e codice

Devi mostrare la data dell'ultimo aggiornamento di un articolo nel footer di ogni post. Oppure inserire un modulo di iscrizione esattamente a metà del testo, senza acrobazie con l'editor di codice e i template. In WordPress, gli shortcode sono lo strumento giusto per farlo.

Uno shortcode è un tag breve tra parentesi quadre: [myshortcode]. WordPress lo trova nel contenuto e lo sostituisce con il risultato di una funzione PHP. Usi continuamente shortcode standard come [gallery] e [embed] senza nemmeno pensarci. Ma il tuo shortcode personale è una leva: scrivi la logica una volta sola e l'editor lo inserisce ovunque con tre clic.

In 10 minuti creerai il tuo primo shortcode funzionante: da una funzione vuota a un tag con attributi e contenuto racchiuso. Il codice è reale, gira su qualsiasi WordPress moderno ed è stato testato su un sito di staging.

💡 Panoramica rapida:

  • La funzione add_shortcode: cosa accetta e come funziona internamente
  • Uno shortcode base [current_year], l'anno corrente in formato testo
  • Uno shortcode con attributi [cta text="Скачать"], un pulsante personalizzato
  • Uno shortcode con contenuto racchiuso [notice]Текст[/notice], un blocco stilizzato
  • Aggiunta tramite plugin o functions.php: pro e contro di ciascun approccio
  • Errori comuni: echo invece di return, conflitti di nome, attributo vuoto in PHP 8+

Cosa può fare add_shortcode e come funziona

La funzione add_shortcode è l'unico modo standard per registrare un nuovo shortcode in WordPress. Accetta due parametri:

  • $tag (stringa), il nome dello shortcode che scriverai tra parentesi quadre. Solo lettere, numeri e underscore. Spazi e caratteri speciali & / < > [ ] = non sono ammessi; WordPress rifiuterà silenziosamente di registrare un tag del genere.
  • $callback (callable), il nome della funzione PHP che verrà eseguita quando lo shortcode viene trovato. Questa funzione genera l'HTML che il visitatore vedrà.

Il codice sorgente della funzione, cinque righe di logica e due controlli di integrità (listato completo su developer.wordpress.org):

1function add_shortcode( $tag, $callback ) {
2 global $shortcode_tags;
3
4 if ( '' === trim( $tag ) ) {
5 _doing_it_wrong(
6 __FUNCTION__,
7 __( 'Invalid shortcode name: Empty name given.' ),
8 '4.4.0'
9 );
10 return;
11 }
12
13 if ( 0 !== preg_match( '@[<>&/\[\]\x00-\x20=]@', $tag ) ) {
14 _doing_it_wrong(
15 __FUNCTION__,
16 sprintf(
17 /* translators: 1: Shortcode name, 2: Space-separated list of reserved characters. */
18 __( 'Invalid shortcode name: %1$s. Do not use spaces or reserved characters: %2$s' ),
19 $tag,
20 '& / < > [ ] ='
21 ),
22 '4.4.0'
23 );
24 return;
25 }
26
27 $shortcode_tags[ $tag ] = $callback;
28}

Il punto chiave: $shortcode_tags, un array globale. WordPress vi memorizza tutti gli shortcode registrati. Durante il rendering del contenuto, il core itera su questo array e chiama la funzione associata per ogni tag trovato. Ne derivano due implicazioni:

  • *Registra sull'hook init.* Se chiami add_shortcode direttamente in un file plugin, potrebbe essere eseguita prima che WordPress sia completamente inizializzato. Il modo corretto è racchiuderla in un hook:
1add_action( 'init', 'my_register_shortcodes' );
2
3function my_register_shortcodes() {
4 add_shortcode( 'mytag', 'my_shortcode_callback' );
5}
  • Un prefisso è obbligatorio. L'array globale è condiviso da tutti i plugin e dal tema. Se chiami uno shortcode [button], il tuo [button] sovrascrive silenziosamente lo stesso shortcode di un plugin per form. Un prefisso come myplugin_ o un'abbreviazione univoca risolve il problema. Negli esempi seguenti uso il prefisso mysite_; in un progetto reale, sostituiscilo con il tuo.

Passo 1: uno shortcode semplice senza parametri

Il percorso più breve per uno shortcode funzionante, tre righe nel functions.php del tuo tema child (o nel plugin Code Snippets, che è più sicuro e non andrà perso con l'aggiornamento del tema).

Aggiungi questo codice e salva:

1add_shortcode( 'mysite_current_year', 'mysite_display_current_year' );
2
3function mysite_display_current_year() {
4 return date( 'Y' );
5}

Ora scrivi [mysite_current_year] in qualsiasi articolo o pagina. Nel front end, al posto dello shortcode apparirà l'anno corrente: "2026".

Cosa succede qui. La funzione mysite_display_current_year non prende argomenti, chiama la funzione PHP date('Y') e restituisce una stringa di quattro cifre. WordPress inserisce questa stringa esattamente dove era stato posizionato lo shortcode. Nessuna magia.

Dove applicarlo nella pratica: l’anno nel footer (© [mysite_current_year]), l’età del progetto nel testo («lavoriamo dal [mysite_current_year]»), l’aggiornamento automatico delle date sulle pagine di conformità legale.

Step 2: uno shortcode con attributi

Uno shortcode senza parametri è utile, ma la vera flessibilità inizia con gli attributi. L’esempio classico, un pulsante con testo e link personalizzabili:

1add_shortcode( 'mysite_cta', 'mysite_cta_button' );
2
3function mysite_cta_button( $atts ) {
4 $atts = shortcode_atts(
5 array(
6 'text' => 'Learn more',
7 'url' => '#',
8 ),
9 $atts,
10 'mysite_cta'
11 );
12
13 return sprintf(
14 '<a href="%s" class="mysite-cta-button">%s</a>',
15 esc_url( $atts['url'] ),
16 esc_html( $atts['text'] )
17 );
18}

Nell’editor si usa così:

1[mysite_cta text="Download plugin" url="https://example.com/myplugin/"]

La funzione shortcode_atts fa tre cose insieme: unisce gli attributi dell’utente con i valori predefiniti, filtra solo le chiavi conosciute e normalizza una stringa vuota trasformandola in array (senza, chiamare [mysite_cta] senza attributi in PHP 8+ genererebbe un TypeError, perché il primo parametro della callback riceverebbe una stringa vuota invece di un array).

*Perché esc_url e esc_html.* Uno shortcode viene inserito da un editor, oggi sei tu, domani un content manager senza accesso al codice. L’escaping dell’output protegge da XSS accidentali se una parentesi o un tag finisce nell’attributo text.

Step 3: uno shortcode con contenuto racchiuso

Alcuni shortcode racchiudono un frammento di testo: [mysite_notice]Важное сообщение[/mysite_notice]. Il contenuto racchiuso arriva nella callback come secondo parametro, $content. Uno scenario tipico, un blocco di avviso stilizzato:

1add_shortcode( 'mysite_notice', 'mysite_notice_box' );
2
3function mysite_notice_box( $atts, $content = null ) {
4 $atts = shortcode_atts(
5 array(
6 'type' => 'info',
7 ),
8 $atts,
9 'mysite_notice'
10 );
11
12 $class = 'notice-' . esc_attr( $atts['type'] );
13
14 return sprintf(
15 '<div class="mysite-notice %s"><p>%s</p></div>',
16 $class,
17 do_shortcode( $content )
18 );
19}

Nota il do_shortcode( $content ). Se l’editor ha inserito un altro shortcode dentro il tuo shortcode (per esempio [mysite_current_year]), questo wrapper lo eseguirà a sua volta. Senza do_shortcode, gli shortcode annidati appariranno come testo tra parentesi quadre, [mysite_current_year] grezzo invece di «2026».

CSS per il blocco, minimale, per iniziare:

1.mysite-notice {
2 border-left: 4px solid #2271b1;
3 background: #f0f6fc;
4 padding: 1em 1.2em;
5 margin: 1.5em 0;
6 border-radius: 4px;
7}
8.mysite-notice.notice-warning {
9 border-left-color: #dba617;
10 background: #fcf9e8;
11}

Aggiungi gli stili al style.css del tema child oppure via Aspetto → Personalizza → CSS aggiuntivo.

Step 4: uno shortcode dentro un plugin (approccio OOP)

Quando hai più di tre shortcode, functions.php diventa una discarica. È il momento di spostare la logica in un plugin separato e, idealmente, in una classe. Ecco lo scheletro di un mini-plugin con uno shortcode:

1<?php
2/**
3 * Plugin Name: MySite Shortcodes
4 * Description: Custom shortcodes for the site.
5 * Version: 1.0.0
6 * Requires PHP: 7.4
7 */
8
9defined( 'ABSPATH' ) || exit;
10
11class MySite_Shortcodes {
12
13 public static function init() {
14 add_action( 'init', array( __CLASS__, 'register' ) );
15 }
16
17 public static function register() {
18 add_shortcode( 'mysite_email', array( __CLASS__, 'email_obfuscated' ) );
19 }
20
21 public static function email_obfuscated( $atts ) {
22 $atts = shortcode_atts(
23 array( 'address' => '' ),
24 $atts,
25 'mysite_email'
26 );
27
28 if ( ! is_email( $atts['address'] ) ) {
29 return '';
30 }
31
32 return sprintf(
33 '<a href="mailto:%1$s">%1$s</a>',
34 antispambot( $atts['address'], 1 )
35 );
36 }
37}
38
39MySite_Shortcodes::init();

Inserisci questo file in wp-content/plugins/mysite-shortcodes/mysite-shortcodes.php e attiva il plugin dal pannello di amministrazione. Lo shortcode [mysite_email address="hello@example.com"] produrrà un link protetto dagli spam bot; la funzione antispambot codifica i caratteri dell’email in entità HTML.

Perché una classe e non un insieme di funzioni. Namespacing: tre shortcode in una classe non entreranno in conflitto con funzioni di terze parti. In più autoloading, in più codice leggibile se il plugin cresce fino a una dozzina di shortcode.

Testare uno shortcode prima di pubblicare

Dopo aver aggiunto il codice, verifica tre scenari:

  • Shortcode senza attributi. Solo [mysite_cta], deve essere renderizzato con i valori predefiniti (testo «Scopri di più», link #).
  • Shortcode con attributi. Un set completo di parametri, tutti i valori vengono recepiti e mostrati correttamente.
  • Errore negli attributi. Una email non valida in [mysite_email], la funzione restituisce silenziosamente una stringa vuota invece di rompere la pagina.

Importante: non usare mai echo dentro una funzione di callback. Uno shortcode deve restituire una stringa tramite return. Se produci HTML con echo, questo apparirà non dove si trova lo shortcode, ma in cima alla pagina, perché WordPress esegue il rendering degli shortcode prima dell’output del contenuto. La stessa logica dei filtri: la funzione restituisce un valore, ed è il motore stesso a decidere dove inserirlo.

Una seconda sfumatura: se lo shortcode non viene visualizzato (vedi [mysite_cta] come testo, non come pulsante), verifica che la funzione sia registrata sull’hook init e non direttamente nel corpo del plugin. Senza init, l’array globale $shortcode_tags potrebbe non essere ancora pronto ad accettare nuovi tag.

Shortcode in un tema vs. in un plugin: cosa scegliere

Criterio

Tema functions.php

Plugin separato

Velocità di avvio

Più veloce - il file è già caricato

Leggermente più lento - file separato

Portabilità

Legato al tema

Funziona con qualsiasi tema

Sopravvivenza agli aggiornamenti

Perso con l’aggiornamento del tema

Vive in modo indipendente

Comodità di modifica

Aspetto → Editor file tema

Editor plugin o FTP

Per quanti shortcode

1-3

4+

La regola: parti da functions.php su un sito di test, costruisci tre shortcode, poi spostali in un plugin. Un aggiornamento del tema sei mesi dopo non seppellirà la tua logica e potrai trasferire gli shortcode su un altro progetto in un minuto.

⁉️🤔 FAQ

Qual è la differenza tra uno shortcode e un blocco Gutenberg?

Uno shortcode è un tag testuale tra parentesi quadre che viene elaborato lato server. Un blocco è un componente dell'editor visuale, un componente React con impostazioni nella sidebar. Gli shortcode sono comparsi in WordPress 2.5 (2008), i blocchi nella 5.0 (2018). Oggi i blocchi sono il modo principale per inserire contenuti dinamici, ma gli shortcode restano rilevanti: sono più semplici da sviluppare, non richiedono conoscenze di JavaScript e funzionano in qualsiasi editor, incluso l'Editor Classico e i page builder.

Uno shortcode è un tag testuale che WordPress sostituisce con il risultato di una funzione PHP durante il rendering della pagina. A differenza di un blocco Gutenberg, uno shortcode non ha un'interfaccia visuale nell'editor: il content manager scrive [myshortcode] come testo e vede l'HTML finito nel front end.

Posso usare uno shortcode dentro un altro shortcode?

Sì. Se la funzione di callback dello shortcode esterno racchiude il contenuto annidato in do_shortcode(), gli shortcode interni funzioneranno correttamente: [notice][current_year][/notice] produrrà un blocco stilizzato con l'anno corrente. Senza do_shortcode(), lo shortcode annidato resterà come testo tra parentesi quadre.

Gli shortcode annidati sono elaborati in modo ricorsivo: WordPress esamina la stringa più volte finché non rimangono tag non elaborati. Ma perché questo funzioni, lo shortcode esterno deve chiamare esplicitamente do_shortcode($content). Altrimenti la stringa [current_year] resterà come testo invece di trasformarsi in "2026".

Perché il mio shortcode non funziona e viene mostrato come testo tra parentesi quadre?

Tre cause comuni. Prima: add_shortcode è chiamato prima dell'hook init, sposta la registrazione dentro add_action('init', ...). Seconda: un errore di battitura nel nome del tag, [my_shortcode] nell'editor ma è registrato myshortcode. Terza: la funzione di callback usa echo invece di return, quindi l'output finisce in cima alla pagina e la posizione dello shortcode è vuota.

Il colpevole più frequente è echo invece di return nella funzione di callback. WordPress chiama i gestori degli shortcode prima di emettere il contenuto principale, quindi il risultato di echo colpisce il buffer di output prima dell'intestazione della pagina. Apri il sorgente della pagina (Ctrl+U): se vedi l'HTML dello shortcode proprio in cima, prima di <html>, è esattamente quello il problema.

Devo fare l'escape dell'output dello shortcode?

Assolutamente sì. Uno shortcode accetta attributi dall'editor, il che significa potenzialmente da qualsiasi utente con permessi di autore o editor. esc_html() per il testo, esc_url() per i link, esc_attr() per gli attributi HTML. L'eccezione è quando restituisci intenzionalmente markup HTML (come <div class="notice">). Ma anche in quel caso, fai l'escape degli attributi all'interno del markup.

Sì, l'escape è obbligatorio per tutto ciò che proviene dagli attributi dello shortcode o dall'input utente. Anche se oggi inserisci gli shortcode solo tu, domani un content manager avrà accesso come editor. esc_html() per il testo, esc_url() per i link, esc_attr() per gli attributi HTML proteggono da XSS accidentale o intenzionale.

Quanti shortcode posso registrare su un sito?

Non c'è un limite tecnico: $shortcode_tags è un normale array PHP, raggiungerai il limite di memoria del server molto dopo il buon senso. In pratica, dopo 15-20 shortcode personalizzati vale la pena chiedersi: è ora di spostarne alcuni in blocchi Gutenberg? Tieni gli shortcode con logica unica (offuscamento email, output condizionato per ruolo). Per shortcode che si limitano a stilizzare il testo ([highlight]), è meglio usare uno stile di blocco o una classe CSS.

Tecnicamente, quanti ne vuoi: l'array $shortcode_tags non ha limiti artificiali. In pratica, più di 20-25 shortcode su un sito suggeriscono che parte della logica dovrebbe essere spostata nei blocchi. Ogni shortcode aggiunge un overhead di parsing del contenuto: prima dell'output, WordPress itera sull'intero array dei tag registrati e cerca corrispondenze nel testo del post.

Conviene scrivere i propri shortcode o bastano i plugin già pronti?

Un plugin già pronto copre la maggior parte delle attività tipiche: form, Contact Form 7, tabelle, TablePress, griglie, qualsiasi page builder. Uno shortcode personalizzato serve quando la logica è specifica del tuo sito e non esiste una soluzione già pronta: mostrare un campo personalizzato esattamente in quel punto della pagina, la data del prossimo webinar dal database, un saluto personalizzato in base al ruolo utente.

In breve: per funzionalità standard, usa un plugin e non scrivere codice. Per logiche uniche, add_shortcode + functions.php o un mini-plugin. Il codice in ognuno degli esempi sopra è sotto le dieci righe. Una volta padroneggiati questi tre schemi (semplice, con attributi, con contenuto annidato), coprirai la stragrande maggioranza dei compiti per cui si scrivono shortcode personalizzati.