WordPress è nato come piattaforma di blog, ma da molto tempo ha smesso di essere solo questo: oggi gestisce portfolio, immobiliari, accademie, directory aziendali e interi negozi. Il pezzo che rende possibile questa versatilità sono i custom post type di WordPress: tipi di contenuto personalizzati che convivono con i post e le pagine, ma con il loro proprio nome, i loro propri campi, i loro propri URL e la loro propria sezione nella bacheca. Se hai mai provato a gestire "progetti", "ricette" o "corsi" basandoti su post normali e categorie, sai quanto velocemente si trasforma in un caos. In questa guida completa imparerai cos'è esattamente un Custom Post Type (CPT), quando ha senso crearlo e quando no, come registrarlo con codice PHP completo e corretto, come aggiungervi tassonomie proprie, come mostrarlo nel tuo tema e quali implicazioni ha per il SEO. Al termine potrai strutturare qualsiasi progetto con la solidità di uno sviluppatore professionale.
Cosa sono i custom post type di WordPress
In WordPress, ogni contenuto è tecnicamente un "post": i post del blog (post), le pagine (page), gli allegati della mediateca (attachment), le revisioni o i menu di navigazione. Tutti vengono salvati nella stessa tabella del database (wp_posts) e si distinguono per il valore della colonna post_type. Un custom post type non è altro che un nuovo valore in quella colonna, registrato da te, con le sue proprie regole: quali caratteristiche ammette (editor, immagine in evidenza, estratto), come si chiama nel menu, quale URL hanno i suoi elementi e se appare o meno nei risultati di ricerca.
Esempi classici in cui i custom post type di WordPress brillano:
- Portfolio: progetti con immagine, cliente e tecnologia utilizzata.
- Immobiliare: proprietà con prezzo, superficie e ubicazione.
- Accademia: corsi e lezioni con durata e livello.
- Ristorante: piatti con allergeni e prezzo.
- Eventi: con data, luogo e capienza.
Infatti, li usi già senza saperlo: i prodotti di WooCommerce sono un CPT chiamato product, e i moduli di quasi ogni plugin vengono anch'essi salvati come tipi di contenuto propri.
Quando creare un CPT (e quando no)
La domanda chiave: questo contenuto è concettualmente distinto da un post del blog? Se la risposta è sì (ha senso elencarlo separatamente, con i propri archivi e la propria struttura), è un candidato per un CPT. Se vuoi solo raggruppare i post per tematica, lo strumento corretto sono le categorie e i tag di sempre.
| Situazione | Soluzione adeguata |
|---|---|
| Separare il blog per tematiche | Categorie |
| Schede di prodotti, corsi, immobili… | Custom Post Type |
| Contrassegnare i post con parole chiave singole | Tag |
| Classificare un CPT (genere di un libro, zona di un immobile) | Tassonomia personalizzata |
| Dati specifici di ogni elemento (prezzo, data, ISBN) | Campi personalizzati (post meta) |
Un'altra decisione preliminare: codice o plugin? Plugin come Custom Post Type UI o Pods permettono di registrare CPT dal pannello senza scrivere PHP, e sono perfettamente validi. In cambio, generano dipendenza: se il plugin viene disattivato, il contenuto non viene cancellato ma scompare dalla bacheca. La registrazione tramite codice, che vedremo ora, è più leggera, portabile e controllabile, ed è come la fanno tutti i temi e i plugin professionali.
Come registrare un custom post type con codice
Tutto ruota attorno a una funzione: register_post_type(), che deve essere eseguita nell'hook init. Questo è un registro completo e commentato per un CPT di portfolio, pronto all'uso:
<?php
function biblioweb_registrar_cpt_proyecto() {
$labels = array(
'name' => 'Proyectos',
'singular_name' => 'Proyecto',
'menu_name' => 'Porfolio',
'add_new' => 'Añadir nuevo',
'add_new_item' => 'Añadir nuevo proyecto',
'edit_item' => 'Editar proyecto',
'new_item' => 'Nuevo proyecto',
'view_item' => 'Ver proyecto',
'search_items' => 'Buscar proyectos',
'not_found' => 'No se han encontrado proyectos',
'not_found_in_trash' => 'No hay proyectos en la papelera',
'all_items' => 'Todos los proyectos',
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'menu_position'=> 20,
'menu_icon' => 'dashicons-portfolio',
'rewrite' => array( 'slug' => 'proyectos', 'with_front' => false ),
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt', 'revisions', 'custom-fields' ),
'show_in_rest' => true, // Necesario para el editor de bloques y la REST API.
'taxonomies' => array(),
);
register_post_type( 'proyecto', $args );
}
add_action( 'init', 'biblioweb_registrar_cpt_proyecto' );
Ripassiamo gli argomenti che generano più dubbi:
public: intrue, il CPT ha URL proprie, appare nella bacheca ed è visibile. Per contenuti interni (ad esempio, testimonianze che vengono mostrate solo incorporate) si può affinare conpublicly_queryableyexclude_from_search.has_archive: crea la pagina di archivio intudominio.com/proyectos/con l'elenco di tutti gli elementi.rewrite: definisce lo slug degli URL.with_front => falseevita di ereditare prefissi dalla struttura dei permalink (come/blog/).supports: quali caselle appaiono nell'editor. Se il tuo CPT non necessita di un editor di testo, rimuovilo e il modulo risulterà più pulito.show_in_rest: indispensabile intruese vuoi usare Gutenberg con questo CPT o consumarlo dalla REST API.menu_icon: qualsiasi icona della libreria Dashicons, o il percorso a un proprio SVG.
Un avviso critico: dopo aver registrato o modificato un CPT, visita Ajustes → Enlaces permanentes e clicca su «Salva modifiche». Questo gesto rigenera le regole di riscrittura; se non lo fai, le nuove URL restituiranno un errore 404 e perderai un bel po' di tempo cercando un errore che non è nel tuo codice.
Dove posizionarlo? In un plugin proprio o in un gestore di snippet come WPCode, che abbiamo analizzato a fondo qui. Evita il functions.php del tema: un CPT è funzionalità, non design, e deve sopravvivere a un cambio di tema.
Tassonomie personalizzate: classificare il tuo nuovo contenuto
Le categorie e i tag standard appartengono agli articoli. Per classificare un CPT la cosa corretta è registrare tassonomie proprie con register_taxonomy(). Continuando con il portfolio, creiamo una tassonomia «Tipo di progetto»:
<?php
function biblioweb_registrar_taxonomia_tipo() {
$labels = array(
'name' => 'Tipos de proyecto',
'singular_name' => 'Tipo de proyecto',
'search_items' => 'Buscar tipos',
'all_items' => 'Todos los tipos',
'edit_item' => 'Editar tipo',
'add_new_item' => 'Añadir nuevo tipo',
);
register_taxonomy(
'tipo_proyecto',
array( 'proyecto' ),
array(
'labels' => $labels,
'hierarchical' => true, // true = como categorías; false = como etiquetas.
'rewrite' => array( 'slug' => 'tipo-proyecto' ),
'show_in_rest' => true,
)
);
}
add_action( 'init', 'biblioweb_registrar_taxonomia_tipo' );
Il parametro hierarchical decide il comportamento: in true funziona come le categorie (con gerarchia padre-figlio e caselle di controllo); in false, come i tag (testo libero). Ogni termine genera automaticamente la propria pagina di archivio: tudominio.com/tipo-proyecto/diseno-web/.
Come mostrare i custom post type nel tuo tema
WordPress risolve la presentazione tramite la gerarchia dei template. Per il nostro CPT proyecto cercherà, in quest'ordine:
single-proyecto.phpper la scheda individuale (se non esiste, usasingle.php).archive-proyecto.phpper l'elenco (se non esiste, usaarchive.phpe poiindex.php).taxonomy-tipo_proyecto.phpper gli archivi della tassonomia.
Se il tuo tema è a blocchi o usi un page builder, normalmente potrai assegnare template al CPT dalla sua interfaccia. E per elenchi personalizzati in qualsiasi template o shortcode, la query si fa con WP_Query:
<?php
$proyectos = new WP_Query( array(
'post_type' => 'proyecto',
'posts_per_page' => 6,
'tax_query' => array(
array(
'taxonomy' => 'tipo_proyecto',
'field' => 'slug',
'terms' => 'diseno-web',
),
),
) );
if ( $proyectos->have_posts() ) :
while ( $proyectos->have_posts() ) : $proyectos->the_post();
the_title( '<h3>', '</h3>' );
the_post_thumbnail( 'medium' );
endwhile;
wp_reset_postdata();
endif;
Non dimenticare mai wp_reset_postdata() dopo un loop personalizzato: ripristina la query principale ed evita strani effetti collaterali nel resto della pagina. Il riferimento completo di tutti gli argomenti disponibili si trova nella documentazione ufficiale dei post type di developer.wordpress.org.
Campi personalizzati: i dati che completano la scheda
Un CPT definisce il «contenitore», ma i dati specifici (prezzo, cliente, data di consegna) vivono in campi personalizzati (post meta). Puoi gestirli in tre modi: con la casella nativa dei campi personalizzati (spartana ma funzionale), con codice tramite register_post_meta() y get_post_meta(), o con plugin specializzati come Advanced Custom Fields (ACF) o Meta Box, che generano interfacce di editing comode con validazione e tipi di campo avanzati. Per progetti seri, la combinazione CPT via codice + ACF per i campi è probabilmente lo standard del settore.
<?php
// Registrar un campo y exponerlo en la REST API:
register_post_meta( 'proyecto', 'cliente', array(
'type' => 'string',
'single' => true,
'show_in_rest' => true,
'sanitize_callback' => 'sanitize_text_field',
) );
// Leerlo en la plantilla:
$cliente = get_post_meta( get_the_ID(), 'cliente', true );
SEO e custom post type: cosa devi controllare
Un CPT ben progettato è una benedizione per la SEO: genera archivi puliti, URL semantiche e una struttura chiara. Ma è opportuno rivedere quattro punti:
- Sitemap: verifica che il tuo plugin SEO includa il nuovo tipo di contenuto nella sitemap XML. Sia Yoast che Rank Math, di cui abbiamo analizzato la versione gratuita, rilevano i CPT pubblici e permettono di attivarli o escluderli per tipo.
- Indicizzazione selettiva: se il CPT è contenuto di supporto (testimonianze, blocchi riutilizzabili), contrassegnalo come non indicizzabile o registralo direttamente con
public => false. - Slug con intenzione:
/proyectos/dice più di/cpt_portfolio/. Lo slug del rewrite è una decisione SEO, e cambiarlo dopo implica reindirizzamenti. - Contenuto nell'archivio: la pagina di archivio generata automaticamente è solitamente un semplice elenco; valutare una pagina con testo introduttivo proprio può fare la differenza per posizionare la keyword principale del tipo di contenuto.
Preguntas frecuentes
Cosa succede al contenuto se disattivo il plugin che registra il CPT?
Nulla viene cancellato: gli elementi rimangono nel database. Semplicemente smettono di essere mostrati nel backend e le loro URL restituiscono 404, perché WordPress non riconosce più quel tipo di contenuto. Riattivando la registrazione (plugin o snippet), tutto riappare intatto. Per questo è importante mantenere la registrazione in qualcosa di indipendente dal tema.
Custom post type o categorie? Non ho ancora chiaro quale usare
Usa le categorie quando vuoi organizzare articoli del blog che condividono il formato. Usa un CPT quando il contenuto ha una natura propria: campi diversi, template diverso e senso come sezione indipendente del sito web. Un suggerimento pratico: se ti ritrovi a voler nascondere quelle «notizie» dal blog principale, è quasi certo che dovrebbero essere un custom post type.
Quanti custom post type posso creare?
Non c'è un limite tecnico rilevante: tutti condividono la tabella wp_posts e il costo di registrare ogni tipo è minimo. Il limite ragionevole è organizzativo: se superi i sei o otto tipi, verifica se alcuni non dovrebbero essere in realtà tassonomie o campi dello stesso tipo. Riserva nomi con prefisso (ad esempio bw_proyecto) se distribuisci il tuo codice, per evitare collisioni con altri plugin.
Perché i miei custom post type danno errore 404?
Nel 95% dei casi, a causa delle regole di riscrittura: WordPress non ha ancora «imparato» le nuove URL. Vai a Ajustes → Enlaces permanentes e salva senza cambiare nulla. Se persiste, verifica che public sia true, che lo slug del rewrite non si scontri con una pagina esistente e che la registrazione venga eseguita nell'hook init ad ogni caricamento, non solo all'attivazione.
Conclusión
I custom post type di WordPress sono lo strumento che trasforma un blog in un vero CMS su misura: portfolio, cataloghi, directory o accademie, ogni contenuto con la sua struttura, le sue URL e il suo posto nel backend. La ricetta professionale si riassume in tre passaggi: registrare il tipo con register_post_type() nell'hook init (e salvare i permalink), classificarlo con tassonomie proprie tramite register_taxonomy(), e completare le schede con campi personalizzati. Da lì, la gerarchia dei template e WP_Query ti danno il controllo totale su come viene mostrato tutto. Inizia con un solo tipo di contenuto reale del tuo progetto, registralo tramite codice in uno snippet o plugin proprio, e verifica nel backend cosa cambia gestire «progetti» veri invece di articoli mascherati. Questa chiarezza strutturale la apprezzerai tu, la apprezzeranno i tuoi clienti e la apprezzerà Google.