Mostrar productos destacados a través de un bucle personalizado en WooCommerce en página de plantilla
Me gustaría mostrar 6 productos destacados de mi tienda WooCommerce en mi plantilla home-page.php. Después de investigar, descubrí que la forma correcta de hacerlo era a través de un bucle personalizado (no deseo usar shortcodes porque me gustaría agregar clases adicionales para estilos, etc.). También encontré que la clave que WooCommerce usa para los productos destacados es '_featured'. Armé el código siguiente para mostrar cualquier producto que elegí como destacado en mi tienda, pero no funciona... Cualquier ayuda es apreciada.
<?php
// Argumentos para la consulta de productos destacados
$args = array(
'post_type' => 'product',
'stock' => 1,
'showposts' => 6,
'orderby' => 'date',
'order' => 'DESC' ,
'meta_query' => array(
array(
'key' => '_featured',
'value' => 0,
'compare' => '>',
'type' => 'numeric'
)
)
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?>
<li>
<?php
if ( has_post_thumbnail( $loop->post->ID ) )
echo get_the_post_thumbnail( $loop->post->ID, 'shop_catalog' );
else
echo '<img src="' . woocommerce_placeholder_img_src() . '" alt="Imagen de producto temporal" width="65px" height="115px" title="Imagen de producto temporal" />';
?>
<h3><?php the_title(); ?></h3>
<?php
echo $product->get_price_html();
woocommerce_template_loop_add_to_cart( $loop->post, $product );
?>
</li>
<?php
endwhile;
wp_reset_query();
?>

Esto ha cambiado en WooCommerce 3.0. Ya no es simplemente un meta_query, sino que ahora incluye un tax_query. Los argumentos ahora son:
$meta_query = WC()->query->get_meta_query();
$tax_query = WC()->query->get_tax_query();
$tax_query[] = array(
'taxonomy' => 'product_visibility',
'field' => 'name',
'terms' => 'featured',
'operator' => 'IN',
);
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['per_page'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'meta_query' => $meta_query,
'tax_query' => $tax_query,
);
Ver woocommerce/includes/class-wc-shortcodes.php

Cambia tus argumentos para que queden así:
$meta_query = WC()->query->get_meta_query();
$meta_query[] = array(
'key' => '_featured',
'value' => 'yes'
);
$args = array(
'post_type' => 'product',
'stock' => 1,
'showposts' => 6,
'orderby' => 'date',
'order' => 'DESC',
'meta_query' => $meta_query
);
Si vas a wp-content/plugins/woocommerce/includes/class-wc-shortcodes.php (@595) puedes encontrar cómo se hace para los shortcodes de WC.

Lo importante a tener en cuenta es que '_featured' no se almacena como un valor numérico. Se almacena como una cadena 'yes' o 'no'. Todo lo demás en la pregunta del OP debería funcionar, funcionó para mí.

Bucle de Productos Destacados en WooCommerce 3
<ul class="products">
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 12,
'tax_query' => array(
array(
'taxonomy' => 'product_visibility',
'field' => 'name',
'terms' => 'featured',
),
),
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
} else {
echo __( 'No se encontraron productos' );
}
wp_reset_postdata();
?>

Según el Wiki de WooCommerce:
Construir WP_Queries personalizados o consultas a la base de datos [para recuperar productos] probablemente romperá tu código en futuras versiones de WooCommerce, ya que los datos se están moviendo hacia tablas personalizadas para un mejor rendimiento.
WooCommerce recomienda usar wc_get_products()
o WC_Product_Query()
en lugar de WP_Query()
o get_posts()
.
He escrito un artículo con el código que usé para lograr lo que necesitas aquí: https://cfxdesign.com/create-a-custom-woocommerce-product-loop-the-right-way/

lo siento, sin ver algo de código escrito, es difícil entender tu artículo. ¿Podrías incluir algún fragmento de código?

@HOY el plugin de incrustación estaba roto; ya está solucionado y ahora puedes ver el código.

gracias, mientras buscaba soluciones, encontré esta que te muestro a continuación. No estoy seguro de en qué se diferencia de la tuya ya que no pude revisar la tuya a fondo, pero es muy corta y me ayudó con un bucle de productos personalizado. https://www.kathyisawesome.com/woocommerce-modifying-product-query/

Sé que esto es bastante antiguo, pero acabo de compartir una solución alternativa aquí y creo que puede ayudar a quienes lleguen a este tema también.
En lugar de usar meta_query
o tax_query
, también puedes usar wc_get_featured_product_ids():
$args = array(
'post_type' => 'product',
'posts_per_page' => 6,
'orderby' => 'date',
'order' => 'DESC',
'post__in' => wc_get_featured_product_ids(),
);
$query = new WP_Query( $args );
¡Espero que ayude!

Basado en: https://github.com/woocommerce/woocommerce/wiki/wc_get_products-and-WC_Product_Query
Yo intentaría:
fuera del bucle:
$args = array (
'limit' => 6,
'orderby' => 'title',
'order' => 'ASC',
'category' => $club_cat,
'stock_status' => 'instock',
'featured' => true,
);
$products = wc_get_products( $args );
en el bucle:
$query = new WC_Product_Query( array(
'limit' => 6,
'orderby' => 'title',
'order' => 'ASC',
'category' => $club_cat,
'stock_status' => 'instock',
'featured' => true,
'return' => 'ids',
) );
$products = $query->get_products();

Las personas deberían empezar a usar wc_get_products porque WooCommerce indicó que esta es la forma estándar de recuperar productos. wc_get_products tiene un argumento "featured" que solo necesita establecerse en true. Así que el código simplemente es el siguiente:
<?php
// Mostrar productos destacados por categoría. En este caso es "shirts" que es el slug de la categoría.
$query_args = array(
'featured' => true,
'category' => array( 'shirts' ),
);
$products = wc_get_products( $query_args );
global $post;
$columns = wc_get_loop_prop( 'columns' );
?>
<div class="woocommerce columns-<?php echo esc_attr( $columns ); ?>">
<?php
woocommerce_product_loop_start();
foreach ($products as $product) {
$post = get_post($product->get_id());
setup_postdata($post);
wc_get_template_part('content', 'product');
}
wp_reset_postdata();
woocommerce_product_loop_end();
?>
</div>
Ver publicación completa aquí: https://jameshwartlopez.com/plugin/get-featured-products-of-a-category/

si miras en la base de datos en la tabla wp_postmeta
verás que meta_key
será _featured
y meta_value
será yes
o no
, así que en lugar del valor 0
o 1
escribe yes
o no
<?php
$q = new WP_Query([
'post_type' => 'product',
'stock' => 1,
'showposts' => 3,
'orderby' => 'date',
'order' => 'DESC',
'meta_query' => [
['key' => '_featured', 'value' => 'yes' ]
]
]);
if ( $q->have_posts() ) :
while ( $q->have_posts() ) : $q->the_post();
// mostrar información del producto
endwhile; wp_reset_query();
endif;
?>

<ul class="products">
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 12,
'tax_query' => array(
array(
'taxonomy' => 'product_visibility',
'field' => 'name',
'terms' => 'featured',
),
),
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
echo '<p>'.get_the_title().'</p>';
endwhile;
} else {
echo __( 'No se encontraron productos' );
}
wp_reset_postdata();
?>
</ul><!--/.products-->

Actualizado para 2021 - Debes usar wc_get_products()
Además, el ejemplo de código de Jameshwart (arriba) no funcionó para mí, así es como configuré los postdata y usé wc_get_template. Probado y funcionando.
$args = array(
'status' => 'publish',
'limit' => 20,
'paginate' => true, //debe ser true para obtener ->total
'return' => 'ids',
);
$products = wc_get_products( $args );
if ($products->total >= 1):
woocommerce_product_loop_start();
foreach($products->products as $pid):
do_action( 'woocommerce_shop_loop' );
$product = get_post($pid);
setup_postdata($GLOBALS['post'] =& $product);
wc_get_template_part('content', 'product');
endforeach;
wp_reset_postdata();
woocommerce_product_loop_end();
endif; //si tenemos productos
