Consulta WP_Query de Taxonomía Personalizada para Todos los Términos en una Taxonomía

6 nov 2010, 00:49:49
Vistas: 67.1K
Votos: 12

¿Hay alguna manera fácil de consultar cualquier entrada que esté etiquetada con cualquier término de una taxonomía específica?

Conozco esta técnica:

$custom_taxonomy_query = new WP_Query( 
 array(
  'taxonomy_name' => 'term_slug',
 )
);

Pero me gustaría poder pasar un comodín en lugar de term_slug, o quizás simplemente una cadena vacía. Esto me daría todas las entradas que están etiquetadas por cualquier término en esa taxonomía, no solo un término específico.

Gracias por tu ayuda, Dave

0
Todas las respuestas a la pregunta 5
2
29

Me encontré con una situación similar Dave. Este código solucionó el problema para mis necesidades. No es la opción más ligera del mundo, pero hace bien el trabajo:

// Obtener todos los IDs de términos en una taxonomía dada
$taxonomy = 'taxonomy_name';
$taxonomy_terms = get_terms( $taxonomy, array(
    'hide_empty' => 0,
    'fields' => 'ids'
) );

// Usar el nuevo argumento tax_query de WP_Query (desde la versión 3.1)
$taxonomy_query = new WP_Query( array(
    'tax_query' => array(
        array(
            'taxonomy' => $taxonomy,
            'field' => 'id',
            'terms' => $taxonomy_terms,
        ),
    ),
) );

Espero que esto te ayude a ti o a cualquier otra persona que esté experimentando este problema.

Kevin

5 dic 2011 20:02:26
Comentarios

Esto fue extremadamente útil para mí. Gracias @kevinlearynet

Tyrun Tyrun
22 oct 2012 23:26:52

Sigue siendo relevante hoy en día

user1676224 user1676224
18 oct 2018 18:59:53
1
12

Algo como esto podría funcionar:

$args = array(
    'post_type' => 'post',
    'tax_query' => array(
        array(
            'taxonomy' => 'your_custom_taxonomy',
            'operator' => 'EXISTS'
        ),
    ),
);
$query = new WP_Query( $args );

Básicamente estás solicitando cualquier publicación asignada a cualquier término dentro de tu taxonomía personalizada.

29 ene 2016 20:44:00
Comentarios

Confirmo que está funcionando.

certainlyakey certainlyakey
3 ene 2021 20:59:02
10

Hola @Dave Morris:

Tienes razón, WordPress decide que si no tienes un término, simplemente ignorará tu taxonomía.

Existen tres (3) enfoques principales que podrías probar:

  1. Usar una consulta SQL completa con $wpdb->get_results(),

  2. Obtener una lista de $post->IDs para todas las publicaciones en tu taxonomía y luego pasarlos usando el argumento 'post__id', o

  3. Anotar el SQL utilizado por WP_Query con uno de los hooks que te permiten agregar un INNER JOIN de SQL haciendo referencia a las tablas de taxonomía.

Intento evitar SQL completo en WordPress hasta que no haya otra opción o simplemente se esté devolviendo una lista de IDs. Y en este caso evitaría extraer una lista de $post-IDs para usar con el argumento 'post__id' porque podría tener problemas de rendimiento e incluso de memoria si tienes muchas publicaciones. Así que nos queda la opción #3.

He creado una clase para extender WP_Query llamada PostsByTaxonomy que utiliza el hook 'posts_join'. Puedes verla aquí:

class PostsByTaxonomy extends WP_Query {
  var $posts_by_taxonomy;
  var $taxonomy;
  function __construct($args=array()) {
    add_filter('posts_join',array(&$this,'posts_join'),10,2);
    $this->posts_by_taxonomy = true;
    $this->taxonomy = $args['taxonomy'];
    unset($args['taxonomy']);
    parent::query($args);
  }
  function posts_join($join,$query) {
    if (isset($query->posts_by_taxonomy)) {
      global $wpdb;
      $join .=<<<SQL
INNER JOIN {$wpdb->term_relationships} ON {$wpdb->term_relationships}.object_id={$wpdb->posts}.ID
INNER JOIN {$wpdb->term_taxonomy} ON {$wpdb->term_taxonomy}.term_taxonomy_id={$wpdb->term_relationships}.term_taxonomy_id
  AND {$wpdb->term_taxonomy}.taxonomy='{$this->taxonomy}'
SQL;
    }
    return $join;
  }
}

Llamarías a esta clase como se muestra a continuación. El argumento 'taxonomy' es obligatorio pero puedes pasar cualquier (¿o todos?) de los otros parámetros que WP_Query espera, como 'posts_per_page':

$query = new PostsByTaxonomy(array(
  'taxonomy' => 'category',
  'posts_per_page' => 25,
));
foreach($query->posts as $post) {
  echo " {$post->post_title}\n";
}

Puedes copiar la clase PostsByTaxonomy al archivo functions.php de tu tema, o puedes usarla dentro de un archivo .php de un plugin que estés desarrollando.

Si deseas probarlo rápidamente, he publicado una versión autocontenida del código en Gist que puedes descargar y copiar en la raíz de tu servidor web como test.php, modificar según tu caso de uso y luego solicitar desde tu navegador usando una URL como http://ejemplo.com/test.php.

ACTUALIZACIÓN

Para omitir las Publicaciones Destacadas de las publicaciones incluidas en la consulta, prueba esto:

$query = new PostsByTaxonomy(array(
  'taxonomy' => 'category',
  'posts_per_page' => 25,
  'caller_get_posts' => true,
));

O si es importante para ti que la clase PostsByTaxonomy nunca incluya publicaciones destacadas, podrías agregarlo al constructor:

  function __construct($args=array()) {
    add_filter('posts_join',array(&$this,'posts_join'),10,2);
    $this->posts_by_taxonomy = true;
    $this->taxonomy = $args['taxonomy'];
    $args['caller_get_posts'] = true;     // Sin Publicaciones Destacadas
    unset($args['taxonomy']);
    parent::query($args);
  }

ACTUALIZACIÓN 2

Después de publicar lo anterior, me enteré de que 'caller_get_posts' quedará obsoleto y se usará 'ignore_sticky_posts' en WordPress 3.1.

6 nov 2010 09:45:53
Comentarios

Mike, gracias por tu ayuda. Por alguna razón no logro que funcione. No está devolviendo solo las publicaciones con términos asignados desde mi taxonomía personalizada. Siempre parece devolver otras publicaciones. Sin embargo, no devuelve todas las publicaciones, así que definitivamente está haciendo algo... ¿Puedo usar la función $query->have_posts() para iterar? Ninguno de los métodos parece funcionarme, de cualquier manera.

Dave Morris Dave Morris
6 nov 2010 15:40:15

Ah, esto es interesante. Encontré la consulta en el registro de mysql que obtiene las dos publicaciones que espero, y funciona. Pero por alguna razón, cuando recorro $query->posts, me devuelve cinco publicaciones. Lo único adicional que noto es que justo después de ejecutarse la consulta de las publicaciones de la taxonomía personalizada, se ejecuta otra consulta que obtiene tres publicaciones más, por sus post_id's. Y luego supongo que las cinco publicaciones se colocan en un único array de resultados.

Dave Morris Dave Morris
6 nov 2010 16:07:54

Creo que lo resolví. Esta consulta personalizada parece incluir publicaciones destacadas (sticky posts), aunque no estén en esa taxonomía personalizada. ¿Alguna idea sobre cómo manejar correctamente las publicaciones destacadas o al menos cómo sacarlas de esta consulta en particular? Gracias, Dave

Dave Morris Dave Morris
6 nov 2010 16:14:12

Bueno, son "pegajosos", ¿verdad? :)

Es un comportamiento extraño, creo, pero si usas caller_get_posts=1 deberían desaparecer:

http://codex.wordpress.org/Function_Reference/query_posts#Sticky_Post_Parameters

Espero que esto ayude.

MikeSchinkel MikeSchinkel
6 nov 2010 18:54:51

Ese if(isset($query->posts_by_taxonomy)) es un buen truco para combinar la metodología orientada a objetos con la metodología de hooks de WordPress.

Jan Fabry Jan Fabry
6 nov 2010 20:21:08

@Jan Fabry - ¡Sí, gracias! Solo me tomó unos 2 años de prueba y error antes de que se me ocurriera. Claro que ahora parece obvio... :)

MikeSchinkel MikeSchinkel
7 nov 2010 01:06:20

¡Eso funcionó! Muchas gracias por tu ayuda. Me gusta aprender nuevos trucos de WordPress, especialmente los de POO.

Dave Morris Dave Morris
7 nov 2010 16:22:30

@Dave Morris - De nada. Por cierto, acabo de enterarme que se llamará 'ignore_sticky_posts' en WP 3.1.

MikeSchinkel MikeSchinkel
7 nov 2010 22:50:02

@MikeSchinkel ¿Qué pasa con la paginación? Esto funciona bien, pero la paginación para esta consulta no está funcionando como debería en mi caso... http://wordpress.stackexchange.com/q/57884/12261

Ajay Patel Ajay Patel
9 jul 2012 14:09:16

¡Ese es un buen truco y todavía funciona! Sin embargo, ¿qué pasa si quisiera incluir un array de taxonomías? ¿2 o 3 taxonomías, qué deberíamos modificar en la consulta?

Rounds Rounds
30 oct 2015 00:06:33
Mostrar los 5 comentarios restantes
6

Deberías poder simplemente establecer la taxonomía y negar para incluir un término...

Ejemplo:

<?php
$your_query = new WP_query;
$your_query->query( array( 'taxonomy' => 'nombre-de-tu-taxonomia' ) );
?>

Lo cual sería básicamente lo mismo que la consulta que realiza un archivo de taxonomía.

6 nov 2010 01:33:32
Comentarios

Eso no funciona.

Dave Morris Dave Morris
6 nov 2010 01:43:21

La línea 1432 de query.php verifica si la taxonomía O el término están vacíos, así que no puedes simplemente no pasar un slug... ¿Alguna otra idea?

Dave Morris Dave Morris
6 nov 2010 01:50:04

@t31os - Esa fue también mi primera reacción; de hecho me ha causado problemas más de una vez porque sigo olvidándolo. Pero @Dave Morris tiene razón; si no es un par taxonomía/término entonces WP_Query simplemente lo descarta.

MikeSchinkel MikeSchinkel
6 nov 2010 09:47:17

Vaya, no sabía eso, es un poco tonto realmente... lección aprendida... :) Medio esperaba que funcionara como los parámetros meta_key / meta_value (no sé por qué)...

t31os t31os
6 nov 2010 10:24:58

@t31os - Sí, WP_Query lamentablemente no está implementado de una manera tan elegante. Son casi 1200 líneas de casos especiales codificados de forma rígida.

MikeSchinkel MikeSchinkel
6 nov 2010 19:06:30

"casi 1200 líneas de casos especiales codificados de forma rígida." ... eso me hizo reír, tuve que dar +1 al comentario... ;)

t31os t31os
6 nov 2010 19:19:19
Mostrar los 1 comentarios restantes
0

En retrospectiva, he hecho una mezcla de las sugerencias de MikeSchinkel y t31os. Es posible inyectar esto en consultas existentes sobre la marcha, pero se requiere WordPress 3.1:

Plugin para obtener un feed RSS de entradas que contengan cualquier término de una taxonomía

5 feb 2011 18:06:56