
🔧 Como tornar um tema WordPress compatível com WooCommerce: um guia completo para programadores
Construir o seu próprio tema e quer integrar uma loja? Tecnicamente, o WooCommerce funciona com qualquer tema, uma vez que é apenas um plugin. Mas «funcionar» não significa «ter bom aspeto»: a grelha de produtos parte-se, as barras laterais deslocam-se e os estilos padrão entram em conflito com os seus.
O problema é mais profundo do que algumas regras de CSS. A partir do WooCommerce 3.3, um tema sem suporte declarado obtém uma renderização simplificada através de shortcodes e um aviso no painel de administração. Perde o controlo total sobre o layout.
Abaixo encontram-se snippets prontos a usar que cobrem tudo, desde a declaração de suporte até um carrinho dinâmico no menu. Cada um foi testado na versão atual do WooCommerce e está organizado por secção, das bases aos ajustes finos.
💡 Visão geral rápida:
- Primeiro, o tema deve declarar explicitamente o suporte ao WooCommerce; sem isso, as substituições de templates e algumas funcionalidades não serão ativadas
- Coloque o código num ficheiro separado (por exemplo
inc/woocommerce.php) que carrega apenas quando o plugin está ativo - Configurar a grelha da loja requer dois filtros: um altera as colunas, o outro adiciona uma classe ao
body - A galeria de produtos, zoom, lightbox e slider são ativados através de chamadas separadas a
add_theme_support - O carrinho no menu deve atualizar via AJAX; utilize o filtro
add_to_cart_fragments
1. Fundação: declarar suporte e verificar se o plugin está ativo
Em primeiro lugar, o tema deve dizer explicitamente ao WooCommerce: «Eu suporto-te.» Sem isto, o plugin não ativa as substituições de templates e mostra um aviso no painel de administração. A partir do WooCommerce 3.3, um tema sem suporte declarado obtém uma renderização simplificada através de shortcodes. Isto funciona, mas limita o seu controlo sobre o layout.
1 add_action( 'after_setup_theme', function() { 2 add_theme_support( 'woocommerce' ); 3 } );
É importante usar o hook after_setup_theme em vez do init, conforme recomendado pela documentação do WooCommerce. Desde a versão 3.3+, pode passar as definições da grelha diretamente:
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 } );
Estes parâmetros definem os valores padrão para o personalizador (WooCommerce → Imagens de Produtos / Catálogo de Produtos) e evitam que os utilizadores tenham de configurar a grelha manualmente.
Verificar se o plugin está ativo
Quando distribui um tema, não pode simplesmente despejar snippets do WooCommerce no final do functions.php porque causarão um erro fatal se o plugin não estiver ativo. O código deve carregar apenas quando o WooCommerce está em execução:
1 define( 'MYTHEME_WOOCOMMERCE_ACTIVE', class_exists( 'WooCommerce' ) ); 2 3 if ( MYTHEME_WOOCOMMERCE_ACTIVE ) { 4 require_once get_template_directory() . '/inc/woocommerce.php'; 5 }
A constante é avaliada uma vez e, depois, em qualquer parte do seu tema, pode envolver as chamadas em if ( MYTHEME_WOOCOMMERCE_ACTIVE ). Isto é mais limpo do que chamar class_exists ou is_plugin_active de cada vez.
2. Gerir os estilos do WooCommerce
O WooCommerce vem com três ficheiros CSS: woocommerce-general, woocommerce-layout e woocommerce-smallscreen. Idealmente, não os remove, mas substitui-os no seu tema. Dessa forma, as extensões de terceiros do WooCommerce que dependem destas classes não se partem. Mas se estiver a escrever tudo de raiz e quiser controlo total, veja como removê-los.
Remover todos os estilos de uma vez:
1 add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );
Ou remover seletivamente:
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' );
Na prática, a segunda opção é mais comum: remove o woocommerce-layout (a grelha baseada em percentagens), mas mantém o woocommerce-general (botões, avisos, formulários) e substitui-os seletivamente com o seu próprio CSS usando maior especificidade.
3. Configurar as páginas da loja
Quantos produtos mostrar
O filtro loop_shop_per_page controla o número de produtos na página da loja e nos arquivos (categorias, etiquetas):
1 function mytheme_woo_posts_per_page( $cols ) { 2 return 12; 3 } 4 add_filter( 'loop_shop_per_page', 'mytheme_woo_posts_per_page' );
Número de colunas na grelha
São necessários dois filtros aqui. Usar apenas loop_shop_columns não chega: ao contrário dos shortcodes do WooCommerce (que têm um wrapper com a classe columns-N), as páginas de loja não têm essa classe. Por isso, adicionamo-la ao 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' );
Agora, no CSS, pode escrever seletores como .columns-4 ul.products li.product, e eles aplicar-se-ão especificamente à grelha da loja.
Título da loja
Por predefinição, o WooCommerce mostra «Shop» como título na página de loja. Se o seu tema já trata dos títulos de arquivo, esta duplicação atrapalha:
1 add_filter( 'woocommerce_show_page_title', '__return_false' );
Se usar the_archive_title(), pode substituir o título pelo nome da página de loja (definido no painel de administração):
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. Galeria de produto: zoom, lightbox e slider
A partir do WooCommerce 3.0, foi introduzida uma nova galeria de produto baseada no FlexSlider, PhotoSwipe e jQuery Zoom. Nas versões 3.0 a 3.2, está desativada por predefinição e requer ativação explícita. A partir da 3.3, a galeria fica ativada para temas não WooCommerce e desativada para temas que declarem suporte; ativa os componentes de que precisa:
1 add_theme_support( 'wc-product-gallery-slider' ); 2 add_theme_support( 'wc-product-gallery-zoom' ); 3 add_theme_support( 'wc-product-gallery-lightbox' );
Pode ativar apenas algumas funcionalidades: por exemplo, slider e zoom sim, mas substituir a lightbox pela sua própria solução Fancybox. Cada diretiva carrega os seus próprios scripts, por isso não ative o que não precisa.
Número de colunas para as miniaturas da galeria (abaixo da imagem principal do produto):
1 function mytheme_woo_product_thumbnails_columns() { 2 return 4; 3 } 4 add_action( 'woocommerce_product_thumbnails_columns', 'mytheme_woo_product_thumbnails_columns' );
5. Produtos relacionados e cross-sells/up-sells
Na página de produto, o WooCommerce mostra os blocos «Produtos relacionados» e «Também pode gostar» (up-sells). A quantidade e a grelha são configuradas separadamente.
Quantos produtos relacionados mostrar:
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' );
Colunas para os blocos de up-sells e relacionados (a mesma história da grelha da loja): alteramos tanto as colunas como a classe no 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' );
Note que woocommerce_output_related_products_args tem dois filtros com prioridades diferentes: mytheme_woo_related_posts_per_page (predefinição 10) altera posts_per_page, e mytheme_woo_related_columns (prioridade 10) altera columns. Não entram em conflito porque trabalham com chaves diferentes no mesmo array $args.
6. Paginação e selo de saldo
Pode substituir as setas da paginação pelos ícones do seu 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' );
Substitua as classes do Font Awesome pelas suas próprias classes de ícones ou SVGs diretos.
O texto no selo de promoção (Sale!) é fácil de alterar. Isto é útil para sites noutros idiomas ou simplesmente para remover o ponto de exclamação:
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' );
Para outros idiomas, substitua 'Sale' pela sua tradução. A tradução será aplicada automaticamente se tiver os ficheiros MO do WooCommerce para esse idioma.
7. Carrinho dinâmico no menu
Este é provavelmente o elemento mais solicitado em qualquer tema de loja: um ícone de carrinho na navegação com o total atual. A implementação consiste em três partes: adicionar o elemento ao menu, gerar o HTML do carrinho e a atualização 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' );
Ponto crítico: **não envolva estas funções em **is_admin(). Os pedidos AJAX do carrinho passam pelo admin-ajax.php e, se a função não estiver disponível no contexto de administração, a atualização do preço no menu simplesmente não funcionará. Substitua theme_location pelo identificador do seu menu (primary no exemplo).
8. Abordagem alternativa: o template woocommerce.php
Os hooks descritos acima são o método mais flexível e seguro em termos de atualizações. Mas se precisar de reformular radicalmente todo o wrapper da loja e da página de produto, existe um caminho através de um template separado.
Crie um ficheiro woocommerce.php na raiz do seu tema (uma cópia do page.php) e substitua o loop principal por uma chamada 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
Este método é mais simples, mas tem um custo: um único template para todas as páginas do WooCommerce (a loja, as categorias e o detalhe do produto). Os ajustes finos (grelhas diferentes, sidebars diferentes em páginas diferentes) tornam-se mais difíceis. Escolha esta abordagem apenas se o seu tema atual realmente não se der bem com o WooCommerce ao nível da marcação e se estiver preparado para aceitar as limitações.
⁉️🤔 Perguntas frequentes
É obrigatório remover os estilos padrão do WooCommerce?
Não é obrigatório. Uma abordagem mais segura é mantê-los e substituir os seletores no seu tema com maior especificidade. Isto preserva a compatibilidade com extensões que dependem das classes padrão do WooCommerce. A remoção completa (
__return_empty_array) só se justifica se estiver a construir um tema de loja de raiz e tiver a certeza de que nenhum plugin de terceiros irá adicionar elementos estilizados para o WooCommerce. Na maioria dos casos, desativar seletivamente owoocommerce-layout(a grelha percentual entra em conflito com flexbox e grids nos temas modernos), mantendo owoocommerce-generale owoocommerce-smallscreene substituindo-os cuidadosamente através da cascata de CSS, é suficiente. Isto dá-lhe uma grelha limpa sem perder compatibilidade.
Porque é que alterar as colunas na loja não funciona?
Porque o filtro loop_shop_columns por si só não é suficiente. O WooCommerce usa classes .columns-N no wrapper para fazer a grelha funcionar, e estas são adicionadas automaticamente apenas aos shortcodes ([products columns="4"]). Nas páginas de loja e arquivos, este wrapper não existe, pelo que precisa de adicionar a classe ao body através do body_class. Os dois filtros da secção 3 resolvem este problema por completo.
O filtro
loop_shop_columnsaltera a variável PHP que o WooCommerce passa para o template, mas a grelha CSS depende da classe do wrapper. Sem a classecolumns-4nobody, os seus estilosul.products li.productnão têm um seletor de contexto e ou não se aplicam ou atingem todas as listas de produtos do site.
Preciso de reconstruir o tema após uma atualização do WooCommerce?
Se estiver a usar hooks (todos os snippets deste artigo), não. Os hooks mudam muito raramente. Se estiver a substituir templates (ficheiros de woocommerce/templates/), sim, precisa de comparar as suas cópias com as versões atuais após cada atualização principal. É exatamente por isso que a documentação oficial recomenda os hooks como o método de personalização preferencial.
Os hooks são um contrato. O WooCommerce garante a sua estabilidade entre versões. Os templates são uma implementação que pode mudar a qualquer momento: novas ações são adicionadas, a marcação muda, as classes são renomeadas. Nos cinco anos em que estes hooks existem (
loop_shop_columnsewoocommerce_output_related_products_args), a sua assinatura nunca mudou, enquanto o ficheirocontent-product.phpfoi atualizado dezenas de vezes durante o mesmo período.
Posso usar o is_admin() para proteger as funções do carrinho?
Não, e esta é uma armadilha comum. Os pedidos AJAX do WooCommerce (adicionar ao carrinho, atualizar quantidade) são processados através do admin-ajax.php; neste contexto, o is_admin() devolve true. Se envolver as funções do carrinho em if ( ! is_admin() ), as atualizações de fragmentos AJAX (add_to_cart_fragments) deixarão de funcionar e o total no ícone do carrinho não mudará sem recarregar a página.
O envolvimento em
! is_admin()só deve ser usado para coisas que não devem ser executadas no admin (saída HTML do front-end), mas as funções de manipulação AJAX devem estar sempre disponíveis. Para o código da secção 7, não use ois_admin()de todo. O próprio WooCommerce chama os callbacks necessários através do seu manipulador AJAX, e a restrição quebrará a lógica.
Como adiciono suporte WooCommerce a um tema de blocos (FSE)?
Para temas de blocos, a declaração de suporte não mudou: o mesmo add_theme_support('woocommerce'). Mas em vez de hooks e substituição de templates PHP, trabalha no Editor do Site: o WooCommerce fornece blocos (Produtos, Pesquisa de Produtos, Carrinho, Finalizar Compra) que insere nos templates através do Appearance → Editor. Os ajustes finos são feitos através do theme.json e das variáveis CSS.
Os temas de blocos mudam fundamentalmente a abordagem: não escreve hooks PHP para o layout, mas monta visualmente as páginas a partir de blocos WooCommerce prontos a usar. Mas a base (
add_theme_supportnofunctions.php) permanece a mesma. Para ajustes finos que não podem ser feitos com blocos (por exemplo, texto personalizado no botão «Adicionar ao Carrinho»), os velhos e bons filtros deste artigo também funcionam em temas FSE.
Que estratégia escolher para o seu projeto
Se está a melhorar um tema existente, comece com os passos 1 e 2: declare o suporte e configure a grelha. Na maioria dos casos, isto é suficiente para que a loja tenha um aspeto decente. Depois, adicione apenas as correções que resolvem problemas específicos: uma galeria partida, uma paginação feia, a falta do carrinho no menu.
Se está a escrever um tema de raiz para venda ou distribuição, percorra a lista completa. Cada item acrescenta algo que os utilizadores esperam de um tema de loja «pronto a usar»: uma grelha personalizável, zoom nos produtos, um ícone de carrinho ao vivo. Coloque o código em inc/woocommerce.php e carregue-o com base na constante. Desta forma, o tema funciona igualmente bem como blog e como loja.
O ponto de partida é sempre o mesmo:
1 add_action( 'after_setup_theme', function() { 2 add_theme_support( 'woocommerce' ); 3 } );
Oito linhas. Todo o resto são detalhes que distinguem um tema «compatível» de um tema «feito à medida».



