get_categories para tipo de contenido personalizado con una taxonomía personalizada adjunta

3 mar 2011, 11:32:14
Vistas: 21.6K
Votos: 8

Básicamente tengo un tipo de contenido personalizado 'products' que tiene dos taxonomías adjuntas... la 'category' normal y una taxonomía personalizada llamada 'brands'.

Tengo una página que es específica de 'brand'. En esta página me gustaría listar todas las 'categorías' que tienen un 'producto' con un término de la 'marca' cuya página estoy visualizando.

Por ejemplo, digamos que estoy en la página de "Nike". Quiero que muestre todas las categorías que tienen un 'producto' con la 'marca' "Nike" adjunta a ellas.

Mi pensamiento inicial es usar get_categories pero no hay forma de definir una taxonomía específica o 'marca'?

$categories = get_categories('orderby=name&depth=1&hide_empty=0&child_of='.$cat);

¿Alguien ha hecho esto antes o conoce una manera de consultar la base de datos directamente para obtener los resultados requeridos?

Cualquier ayuda es apreciada, Gracias

0
Todas las respuestas a la pregunta 3
2

Si deseas listar todas las categorías disponibles para un tipo de contenido personalizado (CPT), este fragmento de código puede ayudarte.

Simplemente usa la función estándar get_categories() y pasa los argumentos $args relacionados con la taxonomía que registraste para tu CPT. Entonces, si definiste tu taxonomía así:

register_taxonomy( 'la_taxonomia_nombrada_en_tu_CPT' );

Luego puedes mostrar la taxonomía a los usuarios en el front-end mediante:

$args = array( 
    'taxonomy'     => 'la_taxonomia_nombrada_en_tu_CPT',
    'orderby'      => 'name',
    'show_count'   => 1,
    'pad_counts'   => 1, 
    'hierarchical' => 1,
    'echo'         => 0
);

$todaslascategorias = get_categories( $args );
echo ( '<pre>' );
print_r( $todaslascategorias );
echo ( '</pre>' );

Verás un objeto que te ayudará en tu camino.

28 ene 2016 16:06:44
Comentarios

Después de horas y un dolor de cabeza, esto funcionó como necesitaba. ¡Gracias! No hay buena documentación sobre cómo imprimir categorías de tipos de post.

Rodrigo Zuluaga Rodrigo Zuluaga
8 jul 2020 01:08:00

Para todos los que se pregunten por qué las categorías aún podrían no aparecer: get_categories() te devuelve categorías que tienen al menos un post asignado, de lo contrario simplemente devolverá un array vacío.

mfru mfru
3 may 2022 13:08:16
8

Hola @daveaspi:

Lo que quieres hacer es común pero no está bien manejado en el núcleo de WordPress. Probablemente haya formas de hacerlo sin SQL personalizado, pero no creo que escalen bien para un gran número de publicaciones. A continuación, te muestro una función que escribí llamada get_cross_referenced_terms() que obtendrá lo que necesitas, junto con un ejemplo de cómo usarla.

El siguiente código se puede colocar en la raíz de tu sitio WordPress en un archivo test.php para verlo en funcionamiento. Luego puedes copiar la función get_cross_referenced_terms() en el archivo functions.php de tu tema o en un archivo .php de un plugin en el que estés trabajando:

<?php 

  include('wp-load.php');

  $nike = get_term_by('slug','nike','brand'); // Esto es solo para ilustrar

  $terms = get_cross_referenced_terms(array(
    'post_type'        => 'product',
    'related_taxonomy' => 'brand',
    'term_id'          => $nike->term_id,
  ));
  foreach($terms as $term) {
    echo "<p>{$term->name}</p>";
  }

function get_cross_referenced_terms($args) {
  global $wpdb;
  $args = wp_parse_args($args,array(
    'post_type'        => 'post',
    'taxonomy'         => 'category',
    'related_taxonomy' => 'post_tag',
    'term_id'          => 0,
  ));
  extract($args);
  $sql = <<<SQL
SELECT DISTINCT
  {$wpdb->terms}.*,
  COUNT(*) AS post_count
FROM
  {$wpdb->terms}
  INNER JOIN {$wpdb->term_taxonomy} ON {$wpdb->terms}.term_id={$wpdb->term_taxonomy}.term_id
  INNER JOIN {$wpdb->term_relationships} ON {$wpdb->term_taxonomy}.term_taxonomy_id={$wpdb->term_relationships}.term_taxonomy_id
  INNER JOIN {$wpdb->posts} ON {$wpdb->term_relationships}.object_id={$wpdb->posts}.ID
  INNER JOIN {$wpdb->term_relationships} related_relationship ON {$wpdb->posts}.ID=related_relationship.object_id
  INNER JOIN {$wpdb->term_taxonomy} related_term_taxonomy ON related_relationship.term_taxonomy_id=related_term_taxonomy.term_taxonomy_id
  INNER JOIN {$wpdb->terms} related_terms ON related_term_taxonomy.term_id=related_terms.term_id
WHERE 1=1
  AND (related_term_taxonomy.taxonomy<>{$wpdb->term_taxonomy}.taxonomy OR related_terms.term_id<>{$wpdb->terms}.term_id)
  AND {$wpdb->posts}.post_type='%s'
  AND {$wpdb->term_taxonomy}.taxonomy='%s'
  AND related_term_taxonomy.taxonomy='%s'
  AND related_terms.term_id=%d
GROUP BY
  {$wpdb->terms}.term_id
SQL;
  $sql = $wpdb->prepare($sql,$post_type,$taxonomy,$related_taxonomy,$term_id);
  $terms = $wpdb->get_results($sql);
  return $terms;
}
3 mar 2011 12:51:28
Comentarios

sí, esa es la consulta SQL de la que estaba hablando :)

Bainternet Bainternet
3 mar 2011 12:59:19

Hola @MikeSchinkel, ¡esto es exactamente lo que necesitaba! Funciona de maravilla. ¡Muchísimas gracias!

daveaspinall daveaspinall
3 mar 2011 13:22:59

@Bainternet muchas gracias por tu aporte también :-)

daveaspinall daveaspinall
3 mar 2011 13:23:31

Una pequeña pregunta, ¿hay alguna manera de limitar la 'profundidad' a 1? ¿Para obtener solo categorías de nivel superior? :-) Gracias chicos

daveaspinall daveaspinall
3 mar 2011 13:29:36

@daveaspi: Agrega AND {$wpdb->term_taxonomy}.parent=0 a la cláusula where.

MikeSchinkel MikeSchinkel
3 mar 2011 13:38:20

@MikeSchinkel, @Bainternet hola chicos, ¿hay alguna manera de agregar una variable en los $args para definir la categoría además de la marca? ej. 'post_type' => 'post', 'taxonomy' => 'category', 'related_taxonomy' => 'post_tag', 'term_id' => 0, 'category_id' => $cat

daveaspinall daveaspinall
7 mar 2011 16:25:01

@davesapi - Eso suena como que debería ser una nueva pregunta.

MikeSchinkel MikeSchinkel
8 mar 2011 01:52:13

@MikeSchinkel ¿cómo deberíamos cambiar la consulta SQL personalizada para que muestre los enlaces a las categorías en lugar de solo los nombres? ¡Gracias!

Ioannis Baltzakis Ioannis Baltzakis
28 sept 2011 01:56:23
Mostrar los 3 comentarios restantes
4

Puedes codificar una consulta SQL personalizada o puedes consultar tu tipo de publicación para esa "marca" y recopilar las categorías para luego mostrarlas, algo como:

// Obtener todas las publicaciones de ese tipo para esa marca específica
$my_query = new WP_Query();
$my_query->query(array(
    'post_type' => 'products', // Tipo de publicación: productos
    'posts_per_page' => -1, // Mostrar todos los posts
    'tax_query' => array( // Consulta de taxonomía
        array(
            'taxonomy' => 'brand', // Taxonomía: marca
            'field' => 'slug', // Campo: slug
            'terms' => $wp_query->query_vars['brand'] // Términos: la marca de la consulta actual
        )
    )
    ));
$my_cats = array(); // Array para almacenar categorías
if ($my_query->have_posts()){
// Recorrer todas las publicaciones y recopilar las categorías en un array
    while ($my_query->have_posts()){
        $my_query->the_post();
        foreach((get_the_category($post->ID)) as $category) { // Obtener categorías de cada post
            if (!in_array($category->cat_ID ,$my_cats)){ // Si la categoría no está en el array
                $my_cats[] = $category->cat_ID; // Agregar ID de categoría al array
            }
        } 
    }
}

y aquí tienes la lista de todos los IDs de categorías en un array $my_cats. del cual puedes obtener toda la información que necesites

3 mar 2011 12:58:21
Comentarios

Sí, mucho más limpio y genial para un sitio pequeño, pero para una gran cantidad de publicaciones podría ser realmente muy lento.

MikeSchinkel MikeSchinkel
3 mar 2011 13:09:04

@MikeSchinkel - sí, esto tomaría un tiempo en un sitio donde cada marca tiene muchos productos, pero supongo que mi "kong SQL fu" no es tan fuerte como el tuyo, ¡maestro!

Bainternet Bainternet
3 mar 2011 13:11:41

¡Ja! ¡No es que lo haya aprendido de la noche a la mañana! Han sido más de 20 años machacando SQL para llegar ahí. :)

MikeSchinkel MikeSchinkel
3 mar 2011 13:13:27

Dices 20+, así que solo me faltan 15 más para llegar ahí.

Bainternet Bainternet
3 mar 2011 13:19:31