Obtener resultados de términos de WordPress que son relativos a una taxonomía diferente | Programar Plus

La siguiente es una publicación invitada de cristian nolen. Christian detalla una situación en la que los datos se organizan de manera inteligente y razonable, pero es un poco complicado consultarlos correctamente. Él detalla una solución que no va demasiado lejos en las malas hierbas para hacerlo bien.

Si alguna vez ha realizado algún desarrollo de WordPress, es probable que haya necesitado crear tipos de publicaciones personalizadas y registrar taxonomías. Trabajar con taxonomías es sencillo cuando la relación es uno a uno, es decir, “Obtén todos los términos de la taxonomía, usa get_terms(), u obtenga todos los términos asociados con la publicación actual, use get_the_terms().”

Pero, ¿qué hace cuando necesita que los resultados devueltos sean relativos a otra taxonomía? Ninguna de las funciones típicas ayuda. Antes de profundizar en la solución, echemos un vistazo más de cerca al problema. El caso de uso es un sitio web de cartera que ofrece una variedad de servicios en múltiples mercados. Nuestra configuración es la siguiente:

  • Tipo de publicación personalizada: Portafolio
  • Taxonomía: Servicios
  • Condiciones: Desarrollo, Ilustración, Fotografía, Diseño de Impresión, Diseño Web
  • Taxonomía: Mercados
  • Condiciones: Cívico, Corporativo, Educación, Salud, Sin Fines de Lucro

Este sitio requiere el uso de una plantilla de taxonomía para ambos Servicios y Mercados. Cuando un visitante llega a una de estas páginas de taxonomía, se muestra un diseño de pestaña que muestra elementos de cartera para mercados asociados (si está viendo un servicio) o servicios asociados (si está viendo un mercado).

Captura de pantalla del diseño de pestañas con la primera pestaña vacía

En la captura de pantalla anterior, estoy mostrando una página de Servicio de fotografía. he usadoget_terms('market') para recuperar los mercados válidos (asignados a un $markets variable). Recorro cada mercado para crear mi pestaña y luego uso WP_Query para recuperar todos los elementos de parque correspondientes. El tax_query El parámetro se usa para restringir los resultados al mercado y servicio actual (definido usando get_query_var('term') en este caso).

Lo primero que notamos es una vergonzosa pestaña vacía de “Civic” que resalta el hecho de que los servicios no se han proporcionado en este mercado. Para empezar, es la primera pestaña que ve un visitante cuando aterriza en esta página.

La solución

Pasé una cantidad significativa de tiempo investigando una resolución. La única solución que encontré involucró consultar la base de datos usando wpdb. Sí, esta era una solución, pero no se sentía bien. Sabía que debe haber una forma integrada de manejar este caso de uso.

Después de profundizar en el Codex de WordPress, descubrí wp_get_object_terms(). La descripción de la función es la siguiente:

Recupera los términos asociados con los objetos dados en las taxonomías proporcionadas.

El ejemplo proporcionado es muy similar a uno que encontraría para get_the_terms(). La clave es que el parámetro del objeto puede ser una matriz.

El objeto al que queremos pasar wp_get_object_terms() es una matriz de ID de publicación. La forma más eficiente que se me ocurrió de construir esta matriz fue usando get_posts() con el parámetro de campos establecido en “ids”. podrías usar WP_Query, pero opté por get_posts() porque:

  1. get_posts() devuelve una matriz frente a un objeto
  2. Nunca confundiré mi inicial get_posts() Llamada de WP_Query utilizado dentro del contenido tabulado.
$service_slug = get_query_var('term');	
$service_post_IDs = get_posts(array(
  'post_type' => 'portfolio',
  'posts_per_page' => -1,
  'tax_query' => array(
    array(
      'taxonomy' => 'service',
      'field' => 'slug',
      'terms' => $service_slug
    )
  ),
  'fields' => 'ids'
));

Lo anterior es cómo obtenemos el subconjunto correcto de ID de publicación. Como se mencionó anteriormente, recupero el slug de servicio actual usando get_query_var('term') y asignarlo a la $service_slug variable. Esto se usa en tax_query para asegurarnos de que solo obtengamos ID de publicación que estén asignados al término de taxonomía actual. Al establecer el fields parámetro a ids el resultado es una matriz indexada de ID de publicaciones.

Ahora que tengo la matriz de ID de publicación, puedo reemplazar get_terms() con lo siguiente:

$markets = wp_get_object_terms($service_post_IDs, 'market');

Cuando actualizo la página, la pestaña “Civic” desaparece y tenemos una pestaña con el contenido correcto.

Captura de pantalla de cómo se corrigió el diseño de la pestaña: sin pestaña vacía Civic

Podría parar aquí. Pero ahora los argumentos usados ​​dentro WP_Query me estan molestando

$args = array(
  'post_type' => 'portfolio',
  'posts_per_page' => -1,
  'tax_query' => array(
    'relation' => 'AND',
    array(
      'taxonomy' => 'market',
      'field'    => 'slug',
      'terms'    => $m->slug,
    ),
    array(
      'taxonomy' => 'service',
      'field'    => 'slug',
      'terms'    => $service_slug,
    ),
  )
);

Sí, lo anterior funciona bien. Pero siento que estoy duplicando mis esfuerzos con respecto a mi tax_query. Lo que podemos hacer es refactorizar tax_query para incluir solo el mercado actual y aprovechar el post__in parámetro con la matriz de ID de puestos de servicio.

$args = array(
  'post_type' => 'portfolio',
  'posts_per_page' => -1,
  'tax_query' => array(
    array(
      'taxonomy' => 'market',
      'field'    => 'slug',
      'terms'    => $m->slug,
    )
  ),
  'post__in' => $service_post_IDs
);

El resultado inicial es el mismo, pero ahora los argumentos de consulta son más delgados y fáciles de leer. Lo más importante es que ahora tiene una plantilla que muestra información válida a sus visitantes.