
🔧 Come rendere un tema WordPress compatibile con WooCommerce: una guida completa per sviluppatori
Stai sviluppando il tuo tema e vuoi integrare un negozio? Tecnicamente WooCommerce funziona con qualsiasi tema, perché è solo un plugin. Ma "funziona" non significa "si vede bene": la griglia prodotti si rompe, le sidebar si spostano e gli stili predefiniti entrano in conflitto con i tuoi.
Il problema è più profondo di qualche regola CSS. A partire da WooCommerce 3.3, un tema senza supporto dichiarato riceve un rendering semplificato tramite shortcode e un avviso nel pannello di amministrazione. Perdi il pieno controllo sul layout.
Di seguito trovi snippet pronti all'uso che coprono tutto, dalla dichiarazione del supporto al carrello live nel menu. Ognuno è stato testato sulla versione corrente di WooCommerce ed è organizzato per sezione, dalle basi alla messa a punto.
💡 Panoramica rapida:
- Prima di tutto, il tema deve dichiarare esplicitamente il supporto a WooCommerce; senza, gli override dei template e alcune funzionalità non si attivano
- Inserisci il codice in un file separato (ad esempio
inc/woocommerce.php) che viene caricato solo quando il plugin è attivo - Per impostare la griglia del negozio servono due filtri: uno cambia il numero di colonne, l'altro aggiunge una classe al
body - Galleria prodotti, zoom, lightbox e slider si attivano con chiamate separate a
add_theme_support - Il carrello nel menu deve aggiornarsi via AJAX; usa il filtro
add_to_cart_fragments
1. Le basi: dichiarare il supporto e verificare che il plugin sia attivo
Prima di tutto, il tema deve dire esplicitamente a WooCommerce: "Ti supporto". Senza, il plugin non attiva gli override dei template e mostra un avviso nel pannello di amministrazione. A partire da WooCommerce 3.3, un tema senza supporto dichiarato riceve un rendering semplificato tramite shortcode. Funziona, ma limita il tuo controllo sul layout.
1 add_action( 'after_setup_theme', function() { 2 add_theme_support( 'woocommerce' ); 3 } );
È importante usare l'hook after_setup_theme anziché init, come raccomandato dalla documentazione di WooCommerce. Dalla versione 3.3 in poi, puoi passare direttamente le impostazioni della griglia:
1 add_action( 'after_setup_theme', function() { 2 add_theme_support( 'woocommerce', array( 3 'thumbnail_image_width' => 150, 4 'single_image_width' => 300, 5 'product_grid' => array( 6 'default_rows' => 3, 7 'min_rows' => 2, 8 'max_rows' => 8, 9 'default_columns' => 4, 10 'min_columns' => 2, 11 'max_columns' => 5, 12 ), 13 ) ); 14 } );
Questi parametri impostano i valori predefiniti per il personalizzatore (WooCommerce → Immagini prodotto / Catalogo prodotti) ed evitano agli utenti di dover configurare la griglia manualmente.
Verificare che il plugin sia attivo
Quando distribuisci un tema, non puoi semplicemente buttare gli snippet WooCommerce in fondo a functions.php, perché causerebbero un errore fatale se il plugin non è attivo. Il codice deve caricarsi solo quando WooCommerce è in esecuzione:
1 define( 'MYTHEME_WOOCOMMERCE_ACTIVE', class_exists( 'WooCommerce' ) ); 2 3 if ( MYTHEME_WOOCOMMERCE_ACTIVE ) { 4 require_once get_template_directory() . '/inc/woocommerce.php'; 5 }
La costante viene valutata una volta sola, e poi in qualsiasi punto del tema puoi racchiudere le chiamate in if ( MYTHEME_WOOCOMMERCE_ACTIVE ). È più pulito che chiamare class_exists o is_plugin_active ogni volta.
2. Gestire gli stili di WooCommerce
WooCommerce include tre file CSS: woocommerce-general, woocommerce-layout e woocommerce-smallscreen. L'ideale è non rimuoverli, ma sovrascriverli nel tuo tema. In questo modo, le estensioni WooCommerce di terze parti che si basano su queste classi non si rompono. Ma se stai scrivendo tutto da zero e vuoi il pieno controllo, ecco come rimuoverli.
Rimuovere tutti gli stili in una volta sola:
1 add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );
Oppure rimuoverli in modo selettivo:
1 function mytheme_remove_woo_styles( $styles ) { 2 unset( $styles['woocommerce-general'] ); 3 unset( $styles['woocommerce-layout'] ); 4 unset( $styles['woocommerce-smallscreen'] ); 5 return $styles; 6 } 7 add_filter( 'woocommerce_enqueue_styles', 'mytheme_remove_woo_styles' );
In pratica, la seconda opzione è più comune: rimuovi woocommerce-layout (la griglia basata su percentuali) ma tieni woocommerce-general (pulsanti, avvisi, moduli) e li sovrascrivi selettivamente con il tuo CSS usando una specificità maggiore.
3. Configurare le pagine del negozio
Quanti prodotti mostrare
Il filtro loop_shop_per_page controlla il numero di prodotti nella pagina del negozio e negli archivi (categorie, tag):
1 function mytheme_woo_posts_per_page( $cols ) { 2 return 12; 3 } 4 add_filter( 'loop_shop_per_page', 'mytheme_woo_posts_per_page' );
Numero di colonne nella griglia
Qui servono due filtri. Usare solo loop_shop_columns non basta: a differenza degli shortcode WooCommerce (che hanno un wrapper con una classe columns-N), le pagine dello shop non hanno questa classe. Quindi la aggiungiamo al body:
1 function mytheme_woo_shop_columns( $columns ) { 2 return 4; 3 } 4 add_filter( 'loop_shop_columns', 'mytheme_woo_shop_columns' ); 5 6 function mytheme_woo_shop_columns_body_class( $classes ) { 7 if ( is_shop() || is_product_category() || is_product_tag() ) { 8 $classes[] = 'columns-4'; 9 } 10 return $classes; 11 } 12 add_filter( 'body_class', 'mytheme_woo_shop_columns_body_class' );
Ora nei CSS puoi scrivere selettori come .columns-4 ul.products li.product, e si applicheranno specificamente alla griglia dello shop.
Titolo dello shop
WooCommerce mostra "Shop" come titolo predefinito nella pagina dello shop. Se il tuo tema gestisce già i titoli degli archivi, questo duplicato è d'intralcio:
1 add_filter( 'woocommerce_show_page_title', '__return_false' );
Se usi the_archive_title(), puoi sostituire il titolo con il nome della pagina shop (impostato nel pannello di amministrazione):
1 function mytheme_woo_archive_title( $title ) { 2 if ( is_shop() && $shop_id = wc_get_page_id( 'shop' ) ) { 3 $title = get_the_title( $shop_id ); 4 } 5 return $title; 6 } 7 add_filter( 'get_the_archive_title', 'mytheme_woo_archive_title' );
4. Galleria prodotto: zoom, lightbox e slider
A partire da WooCommerce 3.0 è stata introdotta una nuova galleria prodotto basata su FlexSlider, PhotoSwipe e jQuery Zoom. Nelle versioni dalla 3.0 alla 3.2 è disabilitata di default e richiede un'attivazione esplicita. Dalla 3.3 in poi, la galleria è abilitata per i temi non WooCommerce e disabilitata per i temi che dichiarano supporto; puoi abilitare tu stesso i componenti che ti servono:
1 add_theme_support( 'wc-product-gallery-slider' ); 2 add_theme_support( 'wc-product-gallery-zoom' ); 3 add_theme_support( 'wc-product-gallery-lightbox' );
Puoi abilitare solo alcune funzionalità: per esempio slider e zoom sì, ma sostituire il lightbox con una tua soluzione Fancybox. Ogni direttiva carica i propri script, quindi non abilitare ciò che non ti serve.
Numero di colonne per le miniature della galleria (sotto l'immagine principale del prodotto):
1 function mytheme_woo_product_thumbnails_columns() { 2 return 4; 3 } 4 add_action( 'woocommerce_product_thumbnails_columns', 'mytheme_woo_product_thumbnails_columns' );
5. Prodotti correlati e cross-sell/up-sell
Nella pagina prodotto, WooCommerce mostra i blocchi "Prodotti correlati" e "Potrebbe piacerti anche" (up-sell). Il loro numero e la griglia si configurano separatamente.
Quanti prodotti correlati mostrare:
1 function mytheme_woo_related_posts_per_page( $args ) { 2 $args['posts_per_page'] = 4; 3 return $args; 4 } 5 add_filter( 'woocommerce_output_related_products_args', 'mytheme_woo_related_posts_per_page' );
Colonne per i blocchi up-sell e correlati (stessa logica della griglia dello shop): modifichiamo sia le colonne sia la classe sul body:
1 function mytheme_woo_single_loops_columns( $columns ) { 2 return 4; 3 } 4 add_filter( 'woocommerce_up_sells_columns', 'mytheme_woo_single_loops_columns' ); 5 6 function mytheme_woo_related_columns( $args ) { 7 $args['columns'] = 4; 8 return $args; 9 } 10 add_filter( 'woocommerce_output_related_products_args', 'mytheme_woo_related_columns', 10 ); 11 12 function mytheme_woo_single_loops_columns_body_class( $classes ) { 13 if ( is_singular( 'product' ) ) { 14 $classes[] = 'columns-4'; 15 } 16 return $classes; 17 } 18 add_filter( 'body_class', 'mytheme_woo_single_loops_columns_body_class' );
Nota che woocommerce_output_related_products_args ha due filtri con priorità diverse: mytheme_woo_related_posts_per_page (default 10) modifica posts_per_page, e mytheme_woo_related_columns (priorità 10) modifica columns. Non entrano in conflitto perché lavorano su chiavi diverse dello stesso array $args.
6. Impaginazione e badge saldi
Puoi sostituire le frecce dell'impaginazione con le icone del tuo tema:
1 function mytheme_woo_pagination_args( $args ) { 2 $args['prev_text'] = '<i class="fa fa-angle-left"></i>'; 3 $args['next_text'] = '<i class="fa fa-angle-right"></i>'; 4 return $args; 5 } 6 add_filter( 'woocommerce_pagination_args', 'mytheme_woo_pagination_args' );
Sostituisci le classi di Font Awesome con le tue classi per icone o con SVG diretti.
Il testo sul badge di sconto (Sale!) è facile da sovrascrivere. È utile per siti in altre lingue o semplicemente per rimuovere il punto esclamativo:
1 function mytheme_woo_sale_flash() { 2 return '<span class="onsale">' . esc_html__( 'Sale', 'woocommerce' ) . '</span>'; 3 } 4 add_filter( 'woocommerce_sale_flash', 'mytheme_woo_sale_flash' );
Per altre lingue, sostituisci 'Sale' con la tua traduzione. La traduzione verrà rilevata automaticamente se disponi dei file MO di WooCommerce per quella lingua.
7. Carrello dinamico nel menu
Questo è probabilmente l'elemento più richiesto in qualsiasi tema per negozio: un'icona del carrello nella navigazione con il totale aggiornato. L'implementazione si compone di tre parti: aggiungere l'elemento al menu, generare l'HTML del carrello e l'aggiornamento via AJAX.
1 // Adding the link to the menu 2 function mytheme_add_menu_cart_item( $items, $args ) { 3 if ( $args->theme_location === 'primary' ) { 4 $css_class = 'menu-item menu-item-type-cart menu-item-type-woocommerce-cart'; 5 if ( is_cart() ) { 6 $css_class .= ' current-menu-item'; 7 } 8 $items .= '<li class="' . esc_attr( $css_class ) . '">'; 9 $items .= mytheme_menu_cart_item(); 10 $items .= '</li>'; 11 } 12 return $items; 13 } 14 add_filter( 'wp_nav_menu_items', 'mytheme_add_menu_cart_item', 10, 2 ); 15 16 // Cart HTML 17 function mytheme_menu_cart_item() { 18 $cart_count = WC()->cart->cart_contents_count; 19 $css_class = 'wpex-menu-cart-total wpex-cart-total-' . intval( $cart_count ); 20 $url = $cart_count ? WC()->cart->get_cart_url() : wc_get_page_permalink( 'shop' ); 21 $html = WC()->cart->get_cart_total(); 22 $html = str_replace( 'amount', '', $html ); 23 24 return '<a href="' . esc_url( $url ) . '" class="' . esc_attr( $css_class ) . '">' 25 . '<span class="cart-icon"></span>' 26 . wp_kses_post( $html ) 27 . '</a>'; 28 } 29 30 // AJAX fragment update 31 function mytheme_menu_cart_link_fragments( $fragments ) { 32 $fragments['.wpex-menu-cart-total'] = mytheme_menu_cart_item(); 33 return $fragments; 34 } 35 add_filter( 'add_to_cart_fragments', 'mytheme_menu_cart_link_fragments' );
Punto critico: **non racchiudere queste funzioni in **is_admin(). Le richieste AJAX del carrello passano attraverso admin-ajax.php e, se la funzione non è disponibile nel contesto admin, l'aggiornamento del prezzo nel menu semplicemente non funzionerà. Sostituisci theme_location con l'identificativo del tuo menu (primary nell'esempio).
8. Approccio alternativo: il template woocommerce.php
Gli hook descritti sopra sono il metodo più flessibile e sicuro in caso di aggiornamenti. Ma se hai bisogno di revisionare radicalmente l'intero involucro del negozio e della pagina prodotto, esiste una strada attraverso un template separato.
Crea un file woocommerce.php nella root del tuo tema (una copia di page.php) e sostituisci il loop principale con una chiamata a woocommerce_content():
1 <?php 2 get_header(); ?> 3 4 <div id="primary" class="content-area"> 5 <main id="main" class="site-main"> 6 <?php woocommerce_content(); ?> 7 </main> 8 </div> 9 10 <?php get_footer(); 11
Questo metodo è più semplice, ma ha un costo: un solo template per tutte le pagine di WooCommerce (il negozio, le categorie e il dettaglio prodotto). Le regolazioni di fino (griglie diverse, sidebar diverse su pagine diverse) diventano più difficili. Scegli questo approccio solo se il tuo tema attuale proprio non va d'accordo con WooCommerce a livello di markup e sei pronto ad accettare le limitazioni.
⁉️🤔 Domande frequenti
È obbligatorio rimuovere gli stili predefiniti di WooCommerce?
Non è obbligatorio. Un approccio più sicuro è mantenerli e sovrascrivere i selettori nel tuo tema con una specificità maggiore. Questo preserva la compatibilità con le estensioni che si basano sulle classi standard di WooCommerce. La rimozione completa (
__return_empty_array) è giustificata solo se stai costruendo un tema per negozio da zero e sai per certo che nessun plugin di terze parti aggiungerà elementi stilizzati per WooCommerce. Nella maggior parte dei casi, disabilitare selettivamentewoocommerce-layout(la griglia percentuale è in conflitto con flexbox e grid nei temi moderni) mantenendowoocommerce-generalewoocommerce-smallscreene sovrascrivendoli con attenzione attraverso la cascata CSS è sufficiente. Questo ti dà una griglia pulita senza perdere compatibilità.
Perché cambiare il numero di colonne nel negozio non funziona?
Perché il solo filtro loop_shop_columns non basta. WooCommerce usa le classi .columns-N sul contenitore per far funzionare la griglia, e queste vengono aggiunte automaticamente solo agli shortcode ([products columns="4"]). Nelle pagine del negozio e negli archivi, questo contenitore non esiste, quindi devi aggiungere la classe al body tramite body_class. I due filtri della sezione 3 risolvono completamente questo problema.
Il filtro
loop_shop_columnscambia la variabile PHP che WooCommerce passa al template, ma la griglia CSS dipende dalla classe del contenitore. Senza la classecolumns-4sulbody, i tuoi stiliul.products li.productnon hanno un selettore di contesto e quindi o non si applicano o colpiscono tutte le liste di prodotti del sito.
Devo ricostruire il tema dopo un aggiornamento di WooCommerce?
Se stai usando gli hook (tutti gli snippet di questo articolo), no. Gli hook cambiano molto raramente. Se stai sovrascrivendo i template (i file da woocommerce/templates/), sì, devi confrontare le tue copie con le versioni attuali dopo ogni aggiornamento maggiore. È proprio per questo che la documentazione ufficiale raccomanda gli hook come metodo di personalizzazione preferito.
Gli hook sono un contratto. WooCommerce ne garantisce la stabilità tra le versioni. I template sono un'implementazione che può cambiare in qualsiasi momento: vengono aggiunte nuove azioni, il markup cambia, le classi vengono rinominate. Nei cinque anni in cui questi hook sono esistiti (
loop_shop_columnsewoocommerce_output_related_products_args), la loro firma non è mai cambiata, mentre il filecontent-product.phpè stato aggiornato decine di volte nello stesso periodo.
Posso usare is_admin() per proteggere le funzioni del carrello?
No, ed è una trappola comune. Le richieste AJAX di WooCommerce (aggiungi al carrello, aggiorna quantità) vengono elaborate tramite admin-ajax.php; in questo contesto, is_admin() restituisce true. Se racchiudi le funzioni del carrello in if ( ! is_admin() ), gli aggiornamenti dei frammenti AJAX (add_to_cart_fragments) smetteranno di funzionare e il totale nell'icona del carrello non cambierà senza un ricaricamento della pagina.
L'uso di
! is_admin()dovrebbe essere limitato a cose che non devono essere eseguite nell'admin (output HTML del front-end), ma le funzioni del gestore AJAX devono essere sempre disponibili. Per il codice nella sezione 7, non usare affattois_admin(). WooCommerce stesso chiama i callback necessari attraverso il suo gestore AJAX e la restrizione romperà la logica.
Come aggiungo il supporto WooCommerce a un tema a blocchi (FSE)?
Per i temi a blocchi, la dichiarazione di supporto non è cambiata: il solito add_theme_support('woocommerce'). Ma invece di hook e sovrascrittura di template PHP, lavori nell'Editor del Sito: WooCommerce fornisce blocchi (Prodotti, Ricerca Prodotto, Carrello, Checkout) che inserisci nei template tramite Appearance → Editor. La messa a punto fine si fa tramite theme.json e le variabili CSS.
I temi a blocchi cambiano radicalmente l'approccio: non scrivi hook PHP per il layout ma assembli visivamente le pagine a partire da blocchi WooCommerce già pronti. Ma le fondamenta (
add_theme_supportinfunctions.php) restano le stesse. Per le regolazioni fini che non si possono fare con i blocchi (ad esempio, un testo personalizzato sul pulsante "Aggiungi al carrello"), i cari vecchi filtri di questo articolo funzionano anche nei temi FSE.
Quale strategia scegliere per il tuo progetto
Se stai migliorando un tema esistente, inizia con i passaggi 1 e 2: dichiara il supporto e configura la griglia. Nella maggior parte dei casi, questo è sufficiente per rendere il negozio presentabile. Poi aggiungi solo le correzioni che risolvono problemi specifici: una galleria rotta, una paginazione brutta, il carrello assente nel menu.
Se stai scrivendo un tema da zero per la vendita o la distribuzione, percorri l'intera lista. Ogni elemento aggiunge qualcosa che gli utenti si aspettano da un tema per negozio "chiavi in mano": una griglia personalizzabile, lo zoom sui prodotti, un'icona del carrello aggiornata in tempo reale. Metti il codice in inc/woocommerce.php e caricalo in base alla costante. In questo modo il tema funziona ugualmente bene sia come blog che come negozio.
Il punto di partenza è sempre lo stesso:
1 add_action( 'after_setup_theme', function() { 2 add_theme_support( 'woocommerce' ); 3 } );
Otto righe. Tutto il resto sono dettagli che distinguono un tema "compatibile" da uno "nato per il negozio".



