¿Cómo personalizar los productos relacionados de WooCommerce?
Tengo las siguientes líneas de código en mi sitio web que muestran los productos relacionados en la parte inferior de mi página de producto individual en WooCommerce...
functions.php:
// mostrar productos sugeridos y relacionados dentro de un div dedicado con diferente columna y número de productos
remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products',20);
remove_action( 'woocommerce_after_single_product', 'woocommerce_output_related_products',10);
add_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20);
function woocommerce_output_related_products() {
$output = null;
ob_start();
woocommerce_related_products(4,4);
$content = ob_get_clean();
if($content) { $output .= $content; }
echo '<div class="clear"></div>' . $output;
}
Como muestra 4 productos que han sido categorizados bajo el mismo nombre, ¿cómo modificaría lo anterior para mostrar las etiquetas relacionadas en su lugar?
Por ejemplo, tengo una categoría de producto llamada 'Automotriz' y dentro de esta categoría, hay algunas etiquetas - 'Holden', 'Ford', 'Toyota', 'Nissan' etc.
Me gustaría que mostrara 4 productos en la parte inferior, relacionados con la etiqueta del producto que el usuario está viendo actualmente.
En primer lugar, no puedes lograr inmediatamente el objetivo que describes con el código que muestras en tu pregunta. Para entender por qué no hay un enfoque directo con ese código, debes analizar lo que estás usando - woocommerce_related_products()
- para hacer lo que has hecho hasta ahora.
En segundo lugar, debes entender, porque de lo contrario no podrás hacer una pregunta precisa, lo cual debería ser tu objetivo principal para asegurarte de obtener una respuesta. Además, debes tener en cuenta que WordPress Development tiene su enfoque principal en preguntas relacionadas con el núcleo de WordPress. Si estás interesado, esto está bajo discusión en WordPress Development Meta, un tema específico es Our wooes and future of platform plugins at WPSE. Por lo tanto, si haces preguntas sobre plugins como WooCommerce, debes desglosarlas para que estén lo más relacionadas posible con funciones del núcleo - ver el siguiente punto - ya que no puedes esperar que la gente conozca cada detalle de cada plugin que usas.
En tercer lugar, ahora profundicemos en lo que está sucediendo. Como dijiste, estás usando woocommerce_related_products()
. Si revisas el código fuente, verás que esta función utiliza woocommerce_get_template()
para obtener la plantilla related.php
. woocommerce_get_template()
a su vez utiliza woocommerce_locate_template()
para localizar la plantilla, y esta última lo hace usando la función del núcleo de WordPress locate_template()
.
Ahora hay una conexión de vuelta al núcleo, lo que lleva a darse cuenta de que las funciones de WooCommerce mencionadas anteriormente - y ojalá inspeccionadas - son esencialmente envoltorios para extender la funcionalidad del núcleo. Otra cosa que quedó clara al analizar las dependencias de funcionalidad es, como dije antes, que necesitas un enfoque diferente para lograr tu objetivo, porque woocommerce_related_products()
- ahora innegablemente obvio - no es el correcto.
Si me has seguido con mis explicaciones y has leído detenidamente hasta ahora, te habrás dado cuenta de que el archivo related.php
contiene lo que buscas. Me refiero especialmente a la función get_related()
, que incluye el hook woocommerce_product_related_posts
y hace uso de las funciones del núcleo wp_get_post_terms()
y get_posts()
- get_related()
se usa para obtener un conjunto de IDs. Además, está el hook woocommerce_related_products_args
, que se puede usar para modificar los argumentos de la consulta de productos relacionados dentro de related.php
, se utiliza WP_Query
para esto. La consulta utiliza los IDs resultantes de la llamada a get_related()
.
Creo que ahora tienes todo lo necesario para resolver tu problema. En realidad, mucho más que eso, esto proporciona una visión casi completa de cómo personalizar los productos relacionados. No he mencionado todas las funcionalidades - funciones y/o hooks - del código fuente inspeccionado, pero definitivamente todas las importantes. Ahora debería quedar más claro cómo la funcionalidad de productos relacionados de WooCommerce se puede rastrear hasta funciones del núcleo de WordPress.
En cuarto lugar, llego al punto donde deberías aplicar tus personalizaciones y lo que deberías haber preguntado. Por ejemplo, así:
WooCommerce tiene el hook woocommerce_product_related_posts
para personalizar la llamada a get_posts()
que determina los productos relacionados.
Código:
// Obtener los posts
$related_posts = get_posts( apply_filters('woocommerce_product_related_posts', array(
'orderby' => 'rand',
'posts_per_page' => $limit,
'post_type' => 'product',
'fields' => 'ids',
'meta_query' => $meta_query,
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $cats_array
),
array(
'taxonomy' => 'product_tag',
'field' => 'id',
'terms' => $tags_array
)
)
) ) );
¿Cómo puedo personalizar esto para lograr mi objetivo? Que es mostrar productos relacionados que estén en la misma categoría de producto - product_cat
- y tengan la(s) misma(s) etiqueta(s) - product_tag
- que el producto individual mostrado.
Sin darte una respuesta concluyente - al menos no si esperabas obtener un código completo y listo para usar - lo primero que probablemente deberías hacer es cambiar el parámetro relation
de tax_query
de OR
a AND
.
Notas:
- Hice esta respuesta más larga y descriptiva teniendo en cuenta la discusión en curso enlazada arriba
- Espero que no te importe que no sea solo una respuesta a tu pregunta, sino que además busca cumplir un propósito educativo general
- esto está sin probar, porque no hay un código listo para usar
- por último, pero no menos importante, es previsible que con el lanzamiento de WooCommerce 2.1 se implementarán algunos cambios significativos en el código, tenlo en cuenta, pero por ahora, a partir de la versión 2.0.19, el código anterior es válido
Edición:
Realmente no deberías editar las clases principales (del plugin) directamente. Es problemático porque tendrás que mantener tus cambios en las actualizaciones, ya que los archivos principales se actualizan y sobrescriben cuando realizas una. Especialmente si es fácilmente evitable como en este caso, el código a continuación hace lo que pretendías hacer de todos modos, que es implementar este cambio a través de tu functions.php
.
Código:
add_filter( 'woocommerce_product_related_posts',
'wpse_123436_change_wc_related_products_relation_to_and' );
function wpse_123436_change_wc_related_products_relation_to_and() {
$get_related_products_args = array(
'orderby' => 'rand',
'posts_per_page' => $limit,
'post_type' => 'product',
'fields' => 'ids',
'meta_query' => $meta_query,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $cats_array
),
array(
'taxonomy' => 'product_tag',
'field' => 'id',
'terms' => $tags_array
)
)
);
return $get_related_products_args;
}
Para WooCommerce versión 2.1.0 y superiores, el hook anterior no funcionará, ya que ya no existe, por lo que la respuesta es utilizable hasta la versión 2.0.20. Pero @NathanPowell descubrió una buena respuesta en StackOverflow sobre el conjunto de hooks disponibles desde la versión 2.1.0 en adelante para la personalización de los productos relacionados.

Muchas gracias @ialocin por la respuesta rápida y detallada. Como medida temporal, simplemente cambié el OR
por AND
en mi archivo wp-content/plugins/woocommerce/classes/abstract/abstract-wc-product.php
y pronto cambiaré esto para hacerlo desde el archivo functions.php
. Gracias de nuevo.

@user1752759 Mira mi edición para hacer esto a través de functions.php

¡Respuesta perfecta! Debería usarse en cualquier guía sobre cómo entender plugins y cómo extenderlos para satisfacer tus necesidades. No estoy seguro de que estos libros existan... Pero aún así :)

@ThdK Gracias, no sé si es tan bueno, pero después de leerlo por primera vez desde que lo escribí, todavía estoy contento con la respuesta, además de que realmente aprecio el cumplido, siempre es agradable escucharlo :) ¿Has probado esto con WC 2.1.x?

Hola @ialocin. La versión editada al final carece de algunos corchetes de cierre y, desafortunadamente, ya no funciona como solución en la versión 2.1.8. Si no es mucha molestia, ¿podrías actualizarlo para mí?

@user1752759 Puedes y deberías corregir los errores que estás viendo tú mismo, editando la respuesta. Además de eso, lo siento, no tengo tiempo en este momento.

@Jk_ ¡Un placer! ¿Tienes esto funcionando? Y si es así, ¿en qué versión de WooCommerce?

No implementé el filtro como mencionaste. Modifiqué el archivo related.php dentro de mi tema para adaptar la consulta. En mi caso quería encontrar productos relacionados basados en 'meta_query'. Pero tu respuesta fue tan inspiradora que tuve que dejar un comentario.

No nos engañemos, chicos. La respuesta aceptada solo llevó al usuario a su objetivo.
El primer problema real está aquí:
<?php
// mostrar productos upsell y relacionados dentro de un div dedicado con diferente número de columnas y productos
remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products',20);
remove_action( 'woocommerce_after_single_product', 'woocommerce_output_related_products',10);
add_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20);
Se elimina una acción y luego se coloca en la MISMA posición de donde se eliminó. El objetivo no está nada claro.
Me encontré con esto al buscar sobre productos relacionados porque no entendía que son las ETIQUETAS y CATEGORÍAS lo que impulsa la función woocommerce_output_related_products
en este plugin.
La mejor respuesta para ESTA pregunta es el siguiente enlace, y tiene todo que ver con el filtro woocommerce_output_related_products_args()
: https://stackoverflow.com/questions/23554993/output-posts-relating-to-the-tags

Esto es realmente bastante gracioso. ¿Por qué podrías preguntar? Porque si hubieras leído mi respuesta con cuidado, habrías visto que usa solo un filtro. Para ser exactos, el único filtro disponible en ese momento, pero lo habrías sabido si realmente hubieras leído lo que escribí y te hubieras tomado el tiempo de mirar los archivos fuente de las diferentes versiones. Solo digo. Aparte de eso, la respuesta que enlazaste explica muy bien los nuevos hooks disponibles desde la versión 2.1.

Lo siento, era tarde en la noche. Esperaba explicar un poco sobre el error obvio en el código del OP.
