16

My theme has styling by category using the following code, which inserts the current category's slug as a CSS class.

<div class="CategorySpecificStyle 
    <?php $category = get_the_category(); echo $category[0]->slug; ?>">
        <?php echo $category[0]->cat_name; ?>
</div> 

Now i'm about to add a large number of new sub-categories, and it seems silly to add them all in CSS when I should be able to just select the parent category of the current post and apply styles to that.

I've been able to get the parent category's name:

$parentcat = get_cat_name($category[0]->category_parent);

But spaces (and capitalization) is an issue... And I can't seem to get the parent category's slug.

I know i'm probably missing a simple step somewhere, but any insight would be greatly appreciated.

9 Answers 9

26

You will need to use the ID value returned by $category[0]->category_parent and pass it through get_term(). Example:

$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;
}
0
8

You will need to query for the parent category data. get_category is pretty much built for doing that.

$category = get_the_category(); 
$parent = get_category($category[0]->category_parent);
echo $parent->slug;

That will return the immediate parent of the category. That is given this set of categories:

  • Cartoon
    • Dog
      • Scooby

The code above will return "Dog" if you give it the ID for "Scooby". If you want the topmost parent category-- "Cartoon"-- no matter how deep the nesting, use something like this:

$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();
}

That also has the advantage of relatively neat error handling.

2
  • Thanks for the answer, and i'll likely use a similar snippet in the future, but it also throws errors if the post in a parent category / category without subcategories.
    – DLR
    Commented Jan 26, 2014 at 0:10
  • @DLR: Yes, I know. I had to leave before I could complete the answer. I was working on something more complex and more robust. See the edit.
    – s_ha_dum
    Commented Jan 26, 2014 at 0:30
1

I found most of the above did not work for Custom Post Types. So I wrote the following function.

Given the ID of the current ( child ) category, it works its way up the chain to give the parent(s) of the category. It returns an array containing url, name, slug and id of parents.

/**
 * @param $category_id
 *
 * @return array        Returns either empty array if no parents or
 *                      an array of  categories from base category[0] to parent category
 *                      The array has a sub array of ['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);
    
    // Sanity check for top parent - ( 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(); // We cant get category 0.
    }


    // We have checked if the parent_id is 0 but double check here for other issues causing empty parent category
    $parent_category = get_term( $parent_category_id, $category_taxonomy);
    if ( empty ( $parent_category ) ){
        return array();
    }

    // Prepare the return array
    $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;
        }

    }

}

For example. In a tree of Home>Products>Platic-Bags>Poly-Bags>3muBags Where the child / current category is 3mu it returned the following:


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/',
  ),
);

0

I like the previous answer from @s_ha_dum, but for getting the top-level category regardless of depth, I used what I consider to be a simpler solution:

$cats = get_the_category();
foreach ( $cats as $cat ) {
    if ( $cat->category_parent == 0 ) {
        return $cat->name; // ...or whatever other attribute/processing you want
    }
}
return ''; // This was from a shortcode; adjust the return value to taste
0

If it can help somebody... to get child cat or parent, depending on the 0 or 1 you put on the $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';
}
0

You can simplify it like this:

  $category   = get_the_category();
  $cat_parent = $category[0]->category_parent;
  $category   = $cat_parent != 0 ? get_term($cat_parent, 'category')->slug : $category[0]->slug;
0

The following function is adapted to return the root category:

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

Usage: get_root_category()->slug

0

All the answers above are good except the "category_parent" now replaced with "parent" from 2018!

In 2021

$custom_tax = 'books_category'; //Custom taxonomy

//Get the terms from post ID
$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;
}
1
  • The parent and category_parent property names should be interchangeable due to the category objects being ran through the _make_cat_compat() function. That said, you are correct in that parent is the new canonical property! I think this would serve better as an edit to the answer in question rather than a brand new answer :)
    – bosco
    Commented Aug 6, 2021 at 16:56
0

For Taxonomies in 2021

$capitulos = get_the_terms( $post->ID, 'capitulos' );
if ($capitulos) {
foreach($capitulos as $capitulo) { if ($capitulo->parent == 0) 
echo '<a href="' . get_term_link($capitulo->term_id) . '">' . $capitulo->name . '</a> ';}
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.