Perché creare un template di pagina personalizzato in WordPress
Ogni tema WordPress arriva con un layout predefinito per le pagine: titolo, contenuto, barra laterale, piè di pagina. Funziona benissimo per una pagina Chi siamo, molto meno quando devi costruire una landing page senza sidebar, una pagina contatti con mappa e modulo affiancati, o un archivio di servizi con una query personalizzata.
In questi casi la soluzione pulita è una sola: creare un template pagina personalizzato WordPress, cioè un file PHP dentro il tema che WordPress mostra nel menu a tendina Modello dell’editor. Da lì puoi assegnarlo a una o più pagine con un clic, senza plugin e senza appesantire il sito.
In questa guida vediamo il procedimento completo per un tema classico, dalla riga di intestazione fino alle varianti per sezioni specifiche del sito, l’approccio alternativo con i template part riutilizzabili e le differenze rispetto ai temi a blocchi (Full Site Editing).
Cosa serve prima di iniziare
- Un tema figlio (child theme): se modifichi direttamente un tema di terze parti, il primo aggiornamento cancellerà il tuo lavoro. Se il tema è tuo, puoi lavorare direttamente al suo interno.
- Accesso ai file via FTP/SFTP, File Manager del pannello hosting oppure un ambiente locale.
- Un editor di codice (VS Code, PhpStorm, Sublime Text). L’editor dei file tema dalla bacheca è sconsigliato: un errore di sintassi PHP può mandare il sito in schermata bianca.
- Un ambiente di staging, o almeno un backup recente, prima di toccare qualsiasi file in produzione.

Come funziona la gerarchia dei template di pagina
WordPress, quando deve mostrare una pagina, cerca i file nel tema attivo seguendo un ordine preciso. Conoscerlo evita molti tentativi a vuoto. Come lettura successiva va bene Come gestire i template pagine su WordPress.
| Priorità | File | Quando viene usato |
|---|---|---|
| 1 | File con Template Name | Se lo hai assegnato manualmente alla pagina dal campo Modello |
| 2 | page-{slug}.php | Esempio: page-contatti.php per la pagina con slug contatti |
| 3 | page-{id}.php | Esempio: page-42.php per la pagina con ID 42 |
| 4 | page.php | Template generico di tutte le pagine |
| 5 | singular.php | Fallback per contenuti singoli |
| 6 | index.php | Ultima spiaggia, sempre presente in un tema valido |
Differenza chiave: i file page-slug.php si attivano da soli ma sono legati a una singola pagina, mentre un template con Template Name è riutilizzabile su quante pagine vuoi e resta selezionabile dalla bacheca. Per un sito che deve essere gestito dal cliente, la seconda strada è quasi sempre la migliore.
Passo 1: creare il file PHP del template
Crea un nuovo file nella cartella del tema (o del tema figlio) e dagli un nome parlante, in minuscolo e con i trattini. Convenzioni diffuse:
template-landing.phptemplate-contatti.phptemplate-full-width.php
Evita di chiamarlo page-qualcosa.php se non vuoi che WordPress lo agganci automaticamente a una pagina con quello slug. C’è altro in Template o Tema per WordPress: quali le differenze.

Passo 2: l’intestazione con Template Name
È la riga che trasforma un file PHP qualsiasi in un template selezionabile. Deve stare nel commento in cima al file, prima di qualsiasi output.
<?php
/**
* Template Name: Landing Page Full Width
* Template Post Type: page
*
* Template personalizzato senza sidebar, pensato per le campagne.
*
* @package MioTema
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header();
?>
Due note importanti:
- Template Name è il nome che l’utente vedrà nel menu a tendina. Scrivilo in modo comprensibile anche per chi non è uno sviluppatore.
- Template Post Type (disponibile da WordPress 4.7) permette di rendere il template disponibile anche per articoli o custom post type. Esempio:
Template Post Type: page, post, servizio. Se ometti la riga, il template vale solo per le pagine.
Passo 3: scrivere la struttura del template
Un template di pagina completo e funzionante può essere semplicissimo. Questo è uno scheletro pronto all’uso:
<?php
/**
* Template Name: Landing Page Full Width
* Template Post Type: page
*/
get_header();
?>
<main id='primary' class='site-main landing-full-width'>
<?php while ( have_posts() ) : the_post(); ?>
<article id='post-<?php the_ID(); ?>' <?php post_class( 'landing-content' ); ?>>
<header class='landing-hero'>
<h1 class='landing-title'><?php the_title(); ?></h1>
<?php if ( has_post_thumbnail() ) : ?>
<div class='landing-thumb'>
<?php the_post_thumbnail( 'full' ); ?>
</div>
<?php endif; ?>
</header>
<div class='entry-content'>
<?php
the_content();
wp_link_pages( array(
'before' => '<div class="page-links">',
'after' => '</div>',
) );
?>
</div>
</article>
<?php endwhile; ?>
</main>
<?php
// Nessuna chiamata a get_sidebar(): il layout resta a tutta larghezza.
get_footer();
Alcuni accorgimenti che fanno la differenza tra un template amatoriale e uno professionale:
- Non chiudere mai il tag PHP finale (
?>) a fine file: eviti spazi vuoti che rompono gli header HTTP. - Mantieni il Loop (
while ( have_posts() )) anche se la pagina ha poco contenuto: senza, funzioni comethe_content()non restituiscono nulla e molti plugin smettono di funzionare. - Usa
post_class()ebody_class()per mantenere le classi CSS che plugin e tema si aspettano. - Escapa sempre l’output dinamico con
esc_html(),esc_url(),esc_attr().
Serve un header o un footer diverso?
Le funzioni di WordPress accettano un parametro per caricare varianti dei file principali:
get_header( 'landing' ); // carica header-landing.php
get_footer( 'minimal' ); // carica footer-minimal.php
get_sidebar( 'servizi' ); // carica sidebar-servizi.php
Se il file richiesto non esiste, WordPress ripiega automaticamente su quello standard: nessun rischio di pagina rotta.
Passo 4: caricare il file nella cartella giusta
Il file va posizionato in /wp-content/themes/nome-del-tema/. Da WordPress 4.7 puoi anche organizzare i template in una sottocartella dedicata, molto più ordinata quando i template diventano cinque o sei:
nome-del-tema/
├── style.css
├── functions.php
├── page.php
├── page-templates/
│ ├── template-landing.php
│ ├── template-contatti.php
│ └── template-servizi.php
└── template-parts/
├── content-hero.php
└── content-cta.php
WordPress scansiona le sottocartelle del tema alla ricerca dell’intestazione Template Name, quindi non serve registrare nulla a mano.

Passo 5: assegnare il template dalla bacheca
- Vai su Pagine e apri (o crea) la pagina che ti interessa.
- Nell’editor a blocchi apri la barra laterale Pagina (icona ingranaggio in alto a destra).
- Cerca la sezione Modello e clicca su Cambia o sul menu a tendina.
- Seleziona il nome che hai indicato in Template Name, ad esempio Landing Page Full Width.
- Clicca su Aggiorna e visualizza la pagina in anteprima.
Con l’editor classico trovi la stessa opzione nel box Attributi pagina, campo Modello.
Non vedi il tuo template nell’elenco? Nel 90% dei casi il problema è uno di questi tre: l’intestazione non è nel primo blocco di commento del file, c’è uno spazio o un carattere prima di <?php, oppure hai caricato il file nel tema padre mentre è attivo il tema figlio (o viceversa).
Creare varianti per sezioni specifiche del sito
Una volta capito il meccanismo, la parte più utile è costruire una famiglia di template, uno per ogni sezione del sito. È esattamente l’approccio che usiamo quando sviluppiamo temi su misura: template piccoli, specializzati, facili da mantenere.
Template per la pagina Servizi con query personalizzata
<?php
/**
* Template Name: Elenco Servizi
*/
get_header();
?>
<main class='site-main pagina-servizi'>
<?php while ( have_posts() ) : the_post(); ?>
<h1><?php the_title(); ?></h1>
<div class='intro'><?php the_content(); ?></div>
<?php endwhile; ?>
<?php
$servizi = new WP_Query( array(
'post_type' => 'servizio',
'posts_per_page' => 9,
'orderby' => 'menu_order',
'order' => 'ASC',
) );
if ( $servizi->have_posts() ) : ?>
<div class='griglia-servizi'>
<?php while ( $servizi->have_posts() ) : $servizi->the_post(); ?>
<article class='card-servizio'>
<a href='<?php echo esc_url( get_permalink() ); ?>'>
<?php the_post_thumbnail( 'medium' ); ?>
<h2><?php echo esc_html( get_the_title() ); ?></h2>
</a>
<p><?php echo esc_html( get_the_excerpt() ); ?></p>
</article>
<?php endwhile; ?>
</div>
<?php
wp_reset_postdata();
endif;
?>
</main>
<?php
get_footer();
Ricordati sempre di wp_reset_postdata() dopo una WP_Query secondaria: senza, il Loop principale resta sporco e rischi titoli o link sbagliati nel resto della pagina.
Template contatti con due colonne
Stessa struttura, cambia solo il markup interno: a sinistra lo shortcode del form, a destra i dati aziendali e la mappa. Un esempio di blocco utile:
<div class='contatti-grid'>
<div class='contatti-form'>
<?php echo do_shortcode( '[contact-form-7 id="123"]' ); ?>
</div>
<aside class='contatti-info'>
<?php the_content(); ?>
</aside>
</div>
Aggiungere una classe al body per il CSS
Per stilizzare facilmente ogni variante, sfrutta le classi che WordPress genera da solo sul tag body, ad esempio page-template-template-landing. Oppure aggiungine una tua da functions.php:
add_filter( 'body_class', 'mumble_body_class_template' );
function mumble_body_class_template( $classes ) {
if ( is_page_template( 'page-templates/template-landing.php' ) ) {
$classes[] = 'layout-landing';
}
return $classes;
}
Caricare CSS o JS solo su quel template
add_action( 'wp_enqueue_scripts', 'mumble_assets_landing' );
function mumble_assets_landing() {
if ( is_page_template( 'page-templates/template-landing.php' ) ) {
wp_enqueue_style(
'mumble-landing',
get_stylesheet_directory_uri() . '/assets/css/landing.css',
array(),
'1.0'
);
}
}
È un dettaglio che incide direttamente sulle performance: nessun file superfluo caricato sulle pagine che non ne hanno bisogno.

L’approccio alternativo: i template part riutilizzabili
Se noti che stai copiando gli stessi blocchi di codice da un template all’altro, fermati: è il momento di usare get_template_part(). Il principio è semplice, scrivi il pezzo una volta sola e lo richiami dove serve.
Crea il file template-parts/content-hero.php:
<section class='hero'>
<h1><?php echo esc_html( $args['titolo'] ?? get_the_title() ); ?></h1>
<?php if ( ! empty( $args['sottotitolo'] ) ) : ?>
<p class='hero-sub'><?php echo esc_html( $args['sottotitolo'] ); ?></p>
<?php endif; ?>
<?php if ( ! empty( $args['cta_url'] ) ) : ?>
<a class='btn btn-primary' href='<?php echo esc_url( $args['cta_url'] ); ?>'>
<?php echo esc_html( $args['cta_label'] ?? 'Scopri di più' ); ?>
</a>
<?php endif; ?>
</section>
E richiamalo da qualsiasi template di pagina passando i parametri (funzionalità disponibile da WordPress 5.5):
get_template_part( 'template-parts/content', 'hero', array(
'sottotitolo' => 'Sviluppo WordPress su misura',
'cta_url' => home_url( '/contatti/' ),
'cta_label' => 'Richiedi un preventivo',
) );
Con la sintassi get_template_part( 'template-parts/content', 'hero' ) WordPress cerca prima content-hero.php e poi ripiega su content.php. È lo stesso meccanismo di fallback della gerarchia dei template, applicato ai frammenti.
Quando usare un template di pagina e quando un template part
| Esigenza | Soluzione consigliata |
|---|---|
| Layout completamente diverso per alcune pagine | Template di pagina con Template Name |
| Blocco ricorrente (hero, CTA, card, breadcrumb) | Template part con get_template_part() |
| Una sola pagina speciale, mai riutilizzata | File page-{slug}.php |
| Variazioni minime (solo colori o spaziature) | Classe CSS aggiuntiva sul body, niente nuovo template |
| Layout gestibile dal cliente senza codice | Pattern di blocchi o template nel tema a blocchi |
Registrare un template da plugin o da functions.php
Se devi distribuire un template senza toccare il tema (per esempio da un plugin proprietario), puoi registrarlo con due filtri:
add_filter( 'theme_page_templates', 'mumble_registra_template' );
function mumble_registra_template( $templates ) {
$templates['mumble-landing'] = 'Landing Mumble';
return $templates;
}
add_filter( 'template_include', 'mumble_carica_template' );
function mumble_carica_template( $template ) {
if ( is_singular( 'page' ) ) {
$assegnato = get_post_meta( get_the_ID(), '_wp_page_template', true );
if ( 'mumble-landing' === $assegnato ) {
return plugin_dir_path( __FILE__ ) . 'templates/landing.php';
}
}
return $template;
}
Il vantaggio è che il template sopravvive al cambio di tema. Lo svantaggio è che perdi il controllo diretto del markup del tema: valutalo caso per caso.
Temi a blocchi (FSE): come cambiano le regole
Se il tuo sito usa un tema a blocchi, il procedimento è diverso. Non esistono file PHP con Template Name: i template sono file HTML composti da markup di blocchi, collocati nella cartella /templates/ del tema, mentre i template part stanno in /parts/.
tema-a-blocchi/
├── style.css
├── theme.json
├── templates/
│ ├── index.html
│ ├── page.html
│ └── page-landing.html
└── parts/
├── header.html
└── footer.html
Per dichiarare un template personalizzato si usa il file theme.json, sezione customTemplates:
{
'version': 3,
'customTemplates': [
{
'name': 'page-landing',
'title': 'Landing Page',
'postTypes': [ 'page' ]
}
]
}
(nel file reale le chiavi vanno tra virgolette doppie, come da standard JSON)
La differenza più rilevante per chi gestisce il sito è che nei temi a blocchi puoi creare un template direttamente dalla bacheca, da Aspetto > Editor > Template > Aggiungi nuovo, senza toccare nessun file. Il template viene salvato nel database e resta modificabile visivamente.
Tabella di confronto rapido
| Aspetto | Tema classico | Tema a blocchi |
|---|---|---|
| Formato file | PHP | HTML con markup di blocchi |
| Dichiarazione | Commento Template Name | Chiave customTemplates in theme.json |
| Posizione | Radice del tema o sottocartella | Cartella /templates/ |
| Frammenti riutilizzabili | get_template_part() | Blocco Template Part in /parts/ |
| Modificabile dalla bacheca | No, serve il codice | Sì, dall’Editor del sito |
| Query personalizzate | WP_Query in PHP | Blocco Loop query |
Come capire quale tema stai usando: se nel menu Aspetto trovi la voce Editor e non trovi Widget, sei su un tema a blocchi. Se vedi Widget e Personalizza, sei su un tema classico.

Errori frequenti e come risolverli
- Il template non compare nel menu Modello: controlla che l’intestazione sia il primo commento del file e che non ci siano righe vuote prima del tag di apertura PHP.
- La pagina è bianca: quasi sempre un errore di sintassi. Attiva
WP_DEBUGinwp-config.phpper leggere il messaggio reale. - Il contenuto della pagina non si vede: manca il Loop, oppure hai usato
the_content()fuori dal Loop. - I plugin smettono di funzionare: hai dimenticato
wp_head()nell’header owp_footer()nel footer personalizzato. - Le modifiche spariscono dopo un aggiornamento: stai lavorando sul tema padre invece che sul tema figlio.
- Il template non si aggiorna a video: svuota la cache del plugin di caching e della CDN, poi ricarica con CTRL+F5.
Checklist finale prima di andare online
- Il file ha l’intestazione Template Name corretta e leggibile.
- Sono presenti
get_header()eget_footer()(oppure i rispettiviwp_head()ewp_footer()). - Il Loop principale è al suo posto.
- Tutti gli output dinamici sono escapati.
- Le
WP_Querysecondarie terminano conwp_reset_postdata(). - CSS e JS specifici sono caricati solo dove servono.
- Il layout è stato verificato su mobile, tablet e desktop.
- Il template è nel tema figlio, così sopravvive agli aggiornamenti.
FAQ sui template di pagina personalizzati in WordPress
Posso creare un template di pagina personalizzato senza saper programmare?
Con un tema a blocchi sì: l’Editor del sito permette di comporre un nuovo template visivamente. Con un tema classico serve almeno una conoscenza di base di PHP e HTML, oppure l’uso di un page builder che gestisca i layout al posto tuo.
Dove si trovano i template di pagina già esistenti nel mio tema?
Nella cartella /wp-content/themes/nome-tema/. Cerca i file che contengono la stringa Template Name nel primo commento, spesso raccolti in una sottocartella come page-templates o templates.
Posso usare lo stesso template su più pagine?
Sì, ed è proprio il suo punto di forza. Un template con Template Name resta disponibile nel menu a tendina e può essere assegnato a un numero illimitato di pagine.
Il template personalizzato rallenta il sito?
Al contrario, se scritto bene lo alleggerisce: puoi rimuovere sidebar, script e sezioni inutili e caricare solo gli asset necessari a quella pagina. I rallentamenti arrivano da query non ottimizzate o immagini pesanti, non dal template in sé.
Che differenza c’è tra template di pagina e tema?
Il tema definisce l’aspetto generale di tutto il sito. Il template di pagina è un singolo file, interno al tema, che sovrascrive il layout predefinito solo per le pagine a cui lo assegni.
Cosa succede se cambio tema?
I template personalizzati appartengono al tema in cui li hai creati: cambiando tema, WordPress non li troverà più e le pagine torneranno al layout predefinito. L’assegnazione resta però salvata nei metadati della pagina, quindi se riattivi il tema originale tutto torna come prima.
Meglio un template personalizzato o un page builder?
Dipende da chi gestirà il sito. Un template su misura offre codice pulito, massima velocità e controllo totale sul markup. Un page builder offre autonomia al cliente a costo di più codice generato e di solito prestazioni inferiori. Nei progetti che sviluppiamo in Mumble Studio la soluzione ideale è spesso ibrida: struttura solida via template PHP o a blocchi, contenuti modificabili tramite blocchi e pattern.
Hai bisogno di una mano con il tuo tema WordPress?
Creare un template pagina personalizzato WordPress è la base per un sito davvero su misura: veloce, mantenibile e coerente con l’identità del brand. Se preferisci affidare a qualcuno lo sviluppo del tema, la migrazione verso un tema a blocchi o l’ottimizzazione delle performance, il team di Mumble Studio è a disposizione per analizzare il tuo progetto e proporti la soluzione più adatta. La stessa conclusione torna anche su wpinprogress.com.