Cómo Obtener el Slug de la Categoría Padre de una Publicación Actual
Mi tema tiene estilos por categoría usando el siguiente código, que inserta el slug de la categoría actual como una clase CSS.
<div class="CategorySpecificStyle
<?php $category = get_the_category(); echo $category[0]->slug; ?>">
<?php echo $category[0]->cat_name; ?>
</div>
Ahora voy a agregar una gran cantidad de subcategorías nuevas, y parece absurdo agregarlas todas en CSS cuando debería poder simplemente seleccionar la categoría padre de la publicación actual y aplicar estilos a esa.
He podido obtener el nombre de la categoría padre:
$parentcat = get_cat_name($category[0]->category_parent);
Pero los espacios (y las mayúsculas) son un problema... Y no puedo obtener el slug de la categoría padre.
Sé que probablemente me estoy perdiendo un paso simple en algún lugar, pero cualquier idea sería muy apreciada.

Necesitarás usar el valor ID devuelto por $category[0]->category_parent
y pasarlo a través de get_term()
. Ejemplo:
$category = get_the_category();
$category_parent_id = $category[0]->category_parent;
if ( $category_parent_id != 0 ) {
$category_parent = get_term( $category_parent_id, 'category' );
$css_slug = $category_parent->slug;
} else {
$css_slug = $category[0]->slug;
}

Necesitarás consultar los datos de la categoría padre. La función get_category
está prácticamente diseñada para eso.
$category = get_the_category();
$parent = get_category($category[0]->category_parent);
echo $parent->slug;
Eso devolverá el padre inmediato de la categoría. Es decir, dado este conjunto de categorías:
- Dibujos animados
- Perro
- Scooby
- Perro
El código anterior devolverá "Perro" si le das el ID de "Scooby". Si deseas la categoría padre superior —"Dibujos animados"— sin importar qué tan profundo esté el anidamiento, usa algo como esto:
$category = get_the_category();
$parent = get_ancestors($category[0]->term_id,'category');
if (empty($parent)) {
$parent[] = array($category[0]->term_id);
}
$parent = array_pop($parent);
$parent = get_category($parent);
if (!is_wp_error($parent)) {
var_dump($parent);
} else {
echo $parent->get_error_message();
}
Eso también tiene la ventaja de un manejo de errores relativamente ordenado.

Gracias por la respuesta, y probablemente usaré un fragmento similar en el futuro, pero también arroja errores si el post está en una categoría padre / categoría sin subcategorías.

Descubrí que la mayoría de lo anterior no funcionaba para Custom Post Types. Así que escribí la siguiente función.
Dado el ID de la categoría actual (hija), recorre la cadena hacia arriba para obtener los padres de la categoría. Devuelve un arreglo que contiene la URL, nombre, slug e ID de los padres.
/**
* @param $category_id
*
* @return array Devuelve un arreglo vacío si no hay padres o
* un arreglo de categorías desde la categoría base[0] hasta la categoría padre
* El arreglo contiene sub arreglos con ['id'] ['name'] ['slug'] ['url']
*
*/
function get_category_parent_array( $category_id, $category_taxonomy = 'category'){
$category_id = abs((int)$category_id);
$category_taxonomy = sanitize_key( $category_taxonomy);
// Verificación para el padre superior - ( id = 0 )
if( 0 == $category_id ){
return array();
}
$child_category = get_term( $category_id, $category_taxonomy);
if( empty($child_category)){
return array();
}
$parent_category_id = $child_category->parent;
if( 0 == $parent_category_id ){
return array(); // No podemos obtener la categoría 0.
}
// Verificamos si parent_id es 0 pero doble verificamos aquí por otros problemas que causen categoría padre vacía
$parent_category = get_term( $parent_category_id, $category_taxonomy);
if ( empty ( $parent_category ) ){
return array();
}
// Preparamos el arreglo de retorno
$parent_array = array();
$parent_array['id'] = $parent_category_id;
$parent_array['slug'] = esc_attr($parent_category->slug);
$parent_array['name'] = esc_attr($parent_category->name);
$parent_array['url'] = esc_url(get_term_link( $parent_category));
if ( 0 == $parent_category_id ){
return $parent_array;
}else{
$new_parent = get_category_parent_array($parent_category_id, $category_taxonomy );
if(! empty( $new_parent ) ){
return array( $new_parent, $parent_array);
}else{
return $parent_array;
}
}
}
Por ejemplo. En un árbol de Inicio>Productos>Bolsas-Plásticas>Bolsas-Polipropileno>Bolsas-3mu Donde la categoría hija/actual es 3mu, devolvió lo siguiente:
array (
0 =>
array (
'id' => 260,
'slug' => 'plastic-bags',
'name' => 'Plastic Bags',
'url' => 'https://example.com/product_category/plastic-bags/',
),
1 =>
array (
'id' => 261,
'slug' => 'polybags',
'name' => 'Polybags',
'url' => 'https://exmapl.com/product_category/polybags/',
),
);

Me gusta la respuesta anterior de @s_ha_dum, pero para obtener la categoría de nivel superior independientemente de la profundidad, utilicé lo que considero una solución más simple:
$cats = get_the_category();
foreach ( $cats as $cat ) {
if ( $cat->category_parent == 0 ) {
return $cat->name; // ...o cualquier otro atributo/procesamiento que desees
}
}
return ''; // Esto provenía de un shortcode; ajusta el valor de retorno según necesites

Si puede ayudar a alguien... para obtener la categoría hija o padre, dependiendo del 0
o 1
que pongas en la $category
$category = get_the_category();
$parent = get_cat_name( $category[0]->category_parent );
if( ! function_exists('get_cat_slug') )
{
function get_cat_slug($cat_id) {
$cat_id = (int) $cat_id;
$category = &get_category($cat_id);
return $category->slug;
}
}
if ( !empty($parent) ) {
$output .= '<H2>' . esc_html( $category[1]->name ) . '</H2>';
} else {
$output .= '<H2>' . esc_html( $category[0]->name ) . '</H2';
}

La siguiente función está adaptada para devolver la categoría raíz:
function get_root_category($category = null) {
if (!$category) $category = get_the_category()[0];
$ancestors = get_ancestors($category->term_id, 'category');
if (empty($ancestors)) return $category;
$root = get_category(array_pop($ancestors));
return $root;
}
Uso:
get_root_category()->slug

Todas las respuestas anteriores son buenas excepto "category_parent" que fue reemplazado por "parent" desde 2018.
En 2021
$custom_tax = 'books_category'; //Taxonomía personalizada
//Obtener los términos desde el ID del post
$terms = get_the_terms( $post->ID, $custom_tax );
$parent_id = $terms[0]->parent;
if ($parent_id != 0){
$parent = get_term( $parent_id, $custom_tax);
echo $parent->slug;
}

Los nombres de las propiedades parent
y category_parent
deberían ser intercambiables ya que los objetos de categoría pasan por la función _make_cat_compat()
. Dicho esto, tienes razón en que parent
es la nueva propiedad canónica. Creo que esto serviría mejor como una edición a la respuesta en cuestión en lugar de una respuesta completamente nueva :)
