Vai al contenuto
🛠 Come aggiungere un campo personalizzato a molti articoli in WordPress

🛠 Come aggiungere un campo personalizzato a molti articoli in WordPress

Un sito su WordPress è cresciuto fino a centinaia di articoli, e ognuno ha bisogno di un nuovo campo personalizzato. Aprire ogni articolo a mano e cliccare «Aggiorna» è un lavoro di mezza giornata, come minimo.

Soprattutto se stai rifinendo un tema o collegando un plugin SEO che ha bisogno della stessa meta_key su tutto il feed degli articoli. Il pannello di amministrazione di WordPress non offre un pulsante «applica a tutti», ma ti dà due modi per risolvere la cosa con il codice.

Qui sotto, entrambi i metodi con snippet pronti all'uso: veloce (una query SQL per l'intero batch) e semplice (un ciclo sugli ID usando la funzione nativa add_post_meta). Scegli in base al compito.

Due monitor mostrano vari blocchi di codice sorgente e file di sviluppo sulla postazione di lavoro di uno sviluppatore

💡 Panoramica rapida:

  • Puoi assegnare in blocco lo stesso campo personalizzato a tutti gli articoli usando add_post_meta in un ciclo, 4 righe di codice.
  • Se ci sono centinaia di articoli e la velocità conta, un INSERT diretto nella tabella wp_postmeta tramite una funzione personalizzata.
  • Entrambi i metodi funzionano tramite il functions.php del tema o il plugin Code Snippets. Fai un backup del database prima di eseguire qualsiasi SQL.

Perché aggiungere un campo a molti articoli in una volta sola

I campi personalizzati (noti anche come post meta) memorizzano informazioni aggiuntive su un record: conteggio visualizzazioni, tag per filtri interni, un flag «preferito», un ID prodotto correlato. Qualsiasi cosa che non rientri nei campi standard post_title e post_content.

Di solito un campo si aggiunge caso per caso: apri un articolo, trovi il blocco «Campi personalizzati» nell'editor, inserisci una coppia chiave-valore. Ma quando il campo deve apparire su tutti i 200 articoli in una volta, il metodo manuale è fuori discussione.

Scenari tipici in cui serve un'azione di massa:

  • Hai attivato un tema child che usa get_post_meta($post_id, 'featured_post', true) per marcare gli articoli in evidenza. Senza un popolamento di massa, i vecchi articoli non appariranno nell'output.
  • Un audit SEO ha richiesto di impostare noindex per un tipo di contenuto specifico tramite un meta campo, anziché via robots.txt.
  • Migrazione da un'altra piattaforma: i dati del vecchio CMS sono finiti in un CSV, e devono essere caricati in wp_postmeta per migliaia di record.

WordPress non ha una funzione nativa add_multiple_posts_meta. Ma ci sono due strade collaudate, scegli in base alla situazione.

Metodo 1. Una query SQL per tutti gli articoli

Il metodo più veloce, un INSERT diretto nella tabella wp_postmeta in una singola transazione. Invece di 200 query individuali al database, ne fai una, e viene eseguita in millisecondi.

Qui sotto, la funzione add_multiple_posts_meta, che accetta un array di ID articolo e rispecchia la firma della funzione nativa add_post_meta: stessi parametri, stesso ordine.

Aggiungi il codice al functions.php del tema child o tramite il plugin Code Snippets. La funzione stessa verifica se un tale campo esiste già per l'articolo (se viene passato $unique = true) e filtra gli ID non validi.

1if( !function_exists( 'add_multiple_posts_meta' ) ){
2 function add_multiple_posts_meta( $post_ids, $meta_key, $meta_value, $unique = false ){
3
4 // If key or ID is not set — exit
5 if( !$meta_key || empty( $post_ids ) ){
6 return false;
7 }
8
9 // One post — pass to native add_post_meta
10 if( is_numeric( $post_ids ) || ( is_array( $post_ids ) && count( $post_ids ) === 1 ) ){
11 return add_post_meta(
12 is_array( $post_ids ) ? $post_ids[0] : $post_ids,
13 $meta_key,
14 $meta_value,
15 $unique
16 );
17 }
18
19 global $wpdb;
20
21 // Filter out invalid IDs and duplicates
22 $valid_post_ids = array_unique(
23 array_filter( $post_ids, function( $post_id ) use ( $wpdb, $meta_key, $unique ){
24 return $post_id
25 && is_numeric( $post_id )
26 && get_post_status( $post_id )
27 && (
28 ! $unique
29 || ! $wpdb->get_var( $wpdb->prepare(
30 "SELECT COUNT(*) FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s",
31 $post_id,
32 $meta_key
33 ) )
34 );
35 } )
36 );
37
38 if( ! count( $valid_post_ids ) ){
39 return false;
40 }
41
42 // Sanitization
43 $meta_key = wp_unslash( $meta_key );
44 $meta_value = sanitize_meta( $meta_key, wp_unslash( $meta_value ), 'post' );
45
46 // Collect data and format strings for a single INSERT
47 $insert_data = [];
48 $insert_formats = [];
49
50 foreach( $valid_post_ids as $post_id ){
51 array_push( $insert_data, $post_id, $meta_key, $meta_value );
52 $insert_formats[] = '(%d, %s, %s)';
53 }
54
55 $sql_string = "INSERT INTO $wpdb->postmeta (`post_id`, `meta_key`, `meta_value`) VALUES "
56 . implode( ', ', $insert_formats );
57
58 // ... unpacks the array into separate arguments for prepare
59 $sql_query = $wpdb->prepare( $sql_string, ...$insert_data );
60
61 return $wpdb->query( $sql_query );
62 }
63}

Cosa succede qui riga per riga. Il controllo !function_exists è una salvaguardia contro i conflitti: se un altro plugin ha già dichiarato una funzione con quel nome, non ci sarà un errore fatale. Il blocco is_numeric($post_ids) passa un singolo ID alla funzione nativa add_post_meta, così la stessa funzione funziona sia con un singolo articolo che con un array. Il filtro array_filter scarta gli ID di bozze, record cancellati e quelli per cui il campo univoco esiste già. La sanitizzazione tramite wp_unslash e sanitize_meta è obbligatoria: senza, i dati serializzati e i caratteri speciali romperanno la query.

*Nota importante su ...$insert_data.* L'operatore ... (splat) scompatta l'array in una lista piatta di argomenti. Senza, $wpdb->prepare riceverebbe un argomento array invece di un insieme di (%d, %s, %s), e la query fallirebbe con un errore di conteggio dei placeholder. PHP 5.6+ (WordPress richiede un minimo di 7.0, quindi sei al sicuro).

Come si usa

Passa un array di ID articolo, la chiave e il valore come una chiamata normale. Il quarto parametro, il flag di unicità: true non aggiungerà il campo se esiste già per l'articolo.

1$post_ids = [ 1, 2, 3, 42, 108 ];
2$meta_key = 'featured_priority';
3$meta_value = 'high';
4$unique = false; // will set for all, even if the field already existed
5
6add_multiple_posts_meta( $post_ids, $meta_key, $meta_value, $unique );

È comodo eseguire una chiamata del genere tramite l'hook init (una volta, poi rimuoverlo) o via WP-CLI con il comando wp eval-file. Dopo l'esecuzione, ricordati di rimuovere il codice da functions.php, altrimenti la funzione si attiverà a ogni caricamento di pagina.

Metodo 2. Ciclo sugli ID con add_post_meta

Se non vuoi toccare SQL direttamente, usa la funzione nativa add_post_meta in un ciclo. Il codice è quattro volte più corto e si basa interamente sul core di WordPress.

1$post_ids = [ 1, 2, 3, 42, 108 ];
2$meta_key = 'featured_priority';
3$meta_value = 'high';
4$unique = false;
5
6foreach( $post_ids as $post_id ){
7 add_post_meta( $post_id, $meta_key, $meta_value, $unique );
8}

Il ciclo itera sull'array e chiama add_post_meta per ogni ID. La funzione stessa controlla l'esistenza del record, l'unicità della chiave (se $unique = true è impostato) e la correttezza dei dati; non serve alcuna validazione aggiuntiva.

Prestazioni. Con un centinaio di articoli, la differenza rispetto alla query SQL è impercettibile. Ma se hai 5.000 record, ogni chiamata a add_post_meta genera un INSERT separato, più gli hook interni (added_post_meta, update_post_meta_cache). A questi volumi, il primo metodo con una query singola sarà 10-20 volte più veloce.

Per operazioni una tantum con un paio di dozzine di articoli, usa il ciclo, non complicare le cose.

Confronto degli approcci

Criterio

Metodo 1 (SQL singola)

Metodo 2 (ciclo add_post_meta)

Velocità su 5.000 articoli

~0,2 sec (1 query)

~3-6 sec (5.000 query)

Complessità del codice

~50 righe con validazione

4 righe

Sicurezza

Sanitizzazione manuale necessaria

add_post_meta gestisce tutto

Hook di WordPress

Non chiamati

added_post_meta, update_post_meta_cache

Quando sceglierlo

Migrazione di massa, import CSV

Modifiche una tantum, fino a un centinaio di articoli

Una regola universale: se ci sono meno di cento articoli e l'operazione è una tantum, usa il ciclo. Se si tratta di sincronizzazione regolare o migrazione di migliaia di record, solo la query diretta con la funzione preparata.

⁉️🤔 Domande frequenti

Posso assegnare un campo in modo selettivo, solo agli articoli di una specifica categoria?

Sì. Ottieni gli ID articolo tramite get_posts con il parametro 'category' => ID_рубрики, poi passa l'array a uno dei due metodi sopra. Per migliaia di articoli, aggiungi 'numberposts' => -1 e 'fields' => 'ids'; la query restituirà solo un array di ID, senza caricare oggetti.

Ecco un esempio pronto: $post_ids = get_posts( [ 'category' => 5, 'numberposts' => -1, 'fields' => 'ids', 'post_type' => 'post' ] );. Poi, chiama add_multiple_posts_meta($post_ids, ...) o un ciclo con add_post_meta.

E se ho bisogno di un valore di campo diverso per articoli diversi?

L'inserimento di massa non funziona qui. Costruisci un array associativo [ ID_поста => значение ] e iteralo in un ciclo con add_post_meta o update_post_meta. Un valore per tutti, SQL; valori diversi per articoli diversi, solo ciclo.

Per oltre 50 articoli con valori univoci, usa update_post_meta invece di add_post_meta: non crea duplicati se il campo esiste già.

È sicuro scrivere query SQL direttamente su wp_postmeta?

È sicuro a due condizioni. Primo: passa sempre i dati attraverso $wpdb->prepare; esegue l'escape dei caratteri speciali e blocca le SQL injection. Secondo: fai un backup completo del database prima di eseguire. Un UPDATE errato senza WHERE, e wp_postmeta viene svuotato per tutti i record.

Comando di backup via WP-CLI: wp db export backup-before-meta.sql. Ripristino: wp db import backup-before-meta.sql.

In cosa differisce add_post_meta da update_post_meta?

add_post_meta aggiunge una nuova riga a wp_postmeta, anche se la chiave esiste già per l'articolo, generando un duplicato. update_post_meta verifica l'esistenza della chiave: se esiste, aggiorna il valore; se no, lo crea. Per il popolamento di massa dove c'è una chiave per articolo, add_post_meta con $unique = true produce lo stesso effetto.

In pratica: add_post_meta($id, 'views', 0, true) creerà il campo una volta e non lo toccherà mai più. update_post_meta($id, 'views', $count) sovrascriverà il valore a ogni chiamata.

Dove dovrei mettere il codice, nel tema o in un plugin?

Per operazioni una tantum, nel functions.php del tema child, con rimozione immediata dopo l'esecuzione. Per attività ricorrenti, impacchettalo come plugin Must-Use (cartella wp-content/mu-plugins/) o aggiungilo a Code Snippets con il flag «Esegui una volta». Il codice in un tema attivo senza rimozione colpirà il database a ogni caricamento di pagina; è un carico non necessario.

Cosa scegliere per il tuo compito

La pratica dimostra: 9 casi su 10 sono coperti dal ciclo con add_post_meta. Sono quattro righe di codice, una funzione nativa e nessuna sorpresa.

Una query SQL diretta è giustificata in due situazioni: migrazione di massa (migliaia di articoli, il tempo è prezioso) e sincronizzazione periodica dove controlli la sanitizzazione in ingresso. Altrimenti, non complicare le cose.

Cosa fare subito:

  • Se devi assegnare un campo a ≤100 articoli, copia il ciclo del secondo metodo, inserisci i tuoi ID ed eseguilo.
  • Se ci sono diverse migliaia di articoli, prendi la funzione del primo metodo, ma testala prima su una copia del sito.
  • In ogni scenario, fai un backup del database prima di eseguire. Non è una precauzione; è una regola.

E tu quale metodo usi di solito per aggiungere campi personalizzati: via pannello di amministrazione, codice o un plugin come ACF? Scrivi nei commenti, è interessante confrontare gli approcci.