woocommercePara quem não sabe, o Woocommerce é um plugin de e-commerce para WordPress que vem ganhando muito mercado ultimamente e concorrendo com outras plataformas super famosas de e-commerce.

Não vou entrar em detalhes sobre os motivos de se usar o plugin ou não. Vou apenas falar sobre um problema que me incomodou recentemente, apesar de gostar muito do Woocommerce.

A documentação da ferramenta mostra uma série de shortcodes nativos bastante úteis para várias finalidades, como carregar os produtos relacionados,   os mais recentes, os produtos em promoção, dentre outros.

 

O Problema

meme_porque2O problema é a impossibilidade de se usar paginação juntamente com os shortcodes que listam produtos.

O problema é tão chato que vários desenvolvedores já concordaram que adicionar essa paginação ao shortcode seria muito útil.

 

Para explicar melhor na prática o problema, se eu quiser usar o shortcode

[recent_products]

para exibir os produtos mais recentes em alguma página específica, não vou poder usar paginação.

 

Resolvendo o Problema

Pra acabar com esse problema, o jeito é carregar os produtos de uma forma mais manual, usando o WP_Query que também é uma mão na roda.
Pra começar,  coloque na sua pagina esse trecho de código, para pegar o valor da query string responsável por informar a página atual:

$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;

 

Adicione agora esse código para carregar os produtos mais recentes:

global $woocommerce_loop, $customWooQuery;
    $atts = array(
        'per_page' => '12',
        'columns' => '3',
        'orderby' => 'date',
        'order' => 'desc'
    );
    extract($atts);
    $meta_query = WC()->query->get_meta_query();
    $args = array(
        'post_type' => 'product',
        'post_status' => 'publish',
        'ignore_sticky_posts' => 1,
        'paged' => $paged,
        'posts_per_page' => $per_page,
        'orderby' => $orderby,
        'order' => $order,
        'meta_query' => $meta_query
    );
    $customWooQuery = new WP_Query(apply_filters('woocommerce_shortcode_products_query', $args, $atts));

Todo esse trecho foi retirado do próprio shortcode do woocommerce responsável por listar os produtos mais recentes. Se você quiser dar uma olhada, é só entrar em woocommerce/includes/class-wc-shortcodes.php.
Eu só alterei alguns detalhes bobos e acrescentei o necessário para a paginação funcionar. Repare no parâmetro ‘paged’. Ele não existia no shortcode original. Um outro detalhe importante é a criação da variável $customWooQuery. Ela será utilizada mais a frente na paginação.

 

Escreva mais isso para apenas exibir os produtos que foram carregados na query:

<?php if ($customWooQuery->have_posts()) : ?>
        <div class="woocommerce columns-<?php echo $columns ?>">
            <?php woocommerce_product_loop_start(); ?>
            <?php while ($customWooQuery->have_posts()) : $customWooQuery->the_post(); ?>
                <?php wc_get_template_part('content', 'product'); ?>
            <?php endwhile; // end of the loop.  ?>
            <?php woocommerce_product_loop_end(); ?>
        </div>
    <?php endif; ?>
    <?php wp_reset_postdata(); ?>

 

Agora para mostrar a paginação e mais algum html gerado pelo próprio Woocommerce:

<?php do_action('woocommerce_after_main_content'); ?>
<?php do_action('woocommerce_after_shop_loop'); ?>

 

Para continuar, agora será necessário alterar o template de paginação do woocommerce. Então não seja apressado! Não altere o código diretamente no plugin. Sempre que for necessário personalizar algum trecho de código do próprio woocommerce, siga os passos que estão na documentação. No caso, simplesmente crie dentro da pasta do tema, uma pasta “woocommerce”, dentro dela uma outra chamada “loop” e dentro dessa, crie o pagination.php e coloque o seguinte conteúdo personalizado da paginação que vai sobrescrever a do woocommerce:

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

global $wp_query, $customWooQuery;

$finalQuery = $wp_query;
if($customWooQuery){
    $finalQuery = $customWooQuery;   
}

if ( $finalQuery->max_num_pages <= 1 )
	return;
?>
<nav class="woocommerce-pagination">
	<?php
		echo paginate_links( apply_filters( 'woocommerce_pagination_args', array(
			'base'         => str_replace( 999999999, '%#%', get_pagenum_link( 999999999 ) ),
			'format'       => '',
			'current'      => max( 1, get_query_var( 'paged' ) ),
			'total'        => $finalQuery->max_num_pages,
			'prev_text'    => '&larr;',
			'next_text'    => '&rarr;',
			'type'         => 'list',
			'end_size'     => 3,
			'mid_size'     => 3
		) ) );
	?>
</nav>

Essa paginação foi retirada também do próprio woocommerce. O que eu mudei no código original foi só pra dizer o seguinte: Se a variavel $customWooQuery não for nula então exiba a paginação de acordo com essa query, senão exiba a paginação normalmente.

 

Concluindo

Para resumir a história, o que você precisa fazer é o seguinte:

  • Crie um page template e insira o código que eu escrevi no post, ou baixe esse page template que eu fiz pra facilitar a vida (Lembrando que  ele funciona apenas para o shortcode [recent_products])
  • Associe este page template a uma página do seu site
  • Altere o template de paginação do woocommerce com o código que escrevi no post, e coloque nesse local: temawoocommercelooppagination.php

Se alguém tiver alguma dúvida ou souber de uma forma mais fácil de se usar o shortcode de produtos do woocommerce junto com a paginação por favor comenta aí!