get_categories para tipo de contenido personalizado con una taxonomía personalizada adjunta
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

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.

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.

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;
}

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

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

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

@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

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

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

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 - 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!

¡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í. :)
