Automatically display titles on Category and Tag Archives

The archive pages in Genesis can be a bit confusing. Other than the URL (and breadcrumbs if you have them turned on), they look exactly the same as the main blog.

Genesis provides a useful feature for adding headlines and intro text to the top of your archive pages. Go to Posts > Categories and edit a category to see the screenshot above. But this requires you to manually type it in for each category. If you have a lot of categories this can be a hassle.

Add this code to your theme’s functions.php to automatically default that field to your category name. If you provide an “Archive Headline” when editing a category, that is used. But if you don’t, the category name is used. This applies to categories, tags, and any custom taxonomies you’ve created.

<?php
/**
* Default Titles for Term Archives
*
* @author Bill Erickson
* @see http://www.billerickson.net/default-category-and-tag-titles
*
* @param string $value
* @param int $term_id
* @param string $meta_key
* @param bool $single
* @return string $vlaue
*/
function ea_default_term_title( $value, $term_id, $meta_key, $single ) {
if( ( is_category() || is_tag() || is_tax() ) && 'headline' == $meta_key && ! is_admin() ) {
// Grab the current value, be sure to remove and re-add the hook to avoid infinite loops
remove_action( 'get_term_metadata', 'ea_default_term_title', 10 );
$value = get_term_meta( $term_id, 'headline', true );
add_action( 'get_term_metadata', 'ea_default_term_title', 10, 4 );
// Use term name if empty
if( empty( $value ) ) {
$term = get_queried_object();
$value = $term->name;
}
}
return $value;
}
add_filter( 'get_term_metadata', 'ea_default_term_title', 10, 4 );
view raw functions.php hosted with ❤ by GitHub

Thanks Joshua Nelson for helping update this code to work with the latest version of Genesis.

And here’s a similar version of the code that uses the term’s description for the “intro text” if that’s empty:

<?php
/**
* Default Descriptions for Term Archives
*
* @author Bill Erickson
* @see http://www.billerickson.net/default-category-and-tag-titles
*
* @param string $value
* @param int $term_id
* @param string $meta_key
* @param bool $single
* @return string $vlaue
*/
function ea_default_term_description( $value, $term_id, $meta_key, $single ) {
if( ( is_category() || is_tag() || is_tax() ) && 'intro_text' == $meta_key && ! is_admin() ) {
// Grab the current value, be sure to remove and re-add the hook to avoid infinite loops
remove_action( 'get_term_metadata', 'ea_default_term_description', 10 );
$value = get_term_meta( $term_id, 'intro_text', true );
add_action( 'get_term_metadata', 'ea_default_term_description', 10, 4 );
// Use term description if empty
if( empty( $value ) ) {
$term = get_queried_object();
$value = $term->description;
}
}
return $value;
}
add_filter( 'get_term_metadata', 'ea_default_term_description', 10, 4 );
view raw functions.php hosted with ❤ by GitHub

Bill Erickson

Bill Erickson is the co-founder and lead developer at CultivateWP, a WordPress agency focusing on high performance sites for web publishers.

About Me
Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions

Comments are closed. Continue the conversation with me on Twitter: @billerickson

Comments

  1. Ben Short says

    Hi Bill,

    I’m having a really strange issue implementing this one, and I can’t for the life of me work out what the issue is.

    For some reason, the filter is outputting the name of the category that has an ID 1 less than the current category… i.e. if I’m on category ID 161, it’s outputting the name of category ID 160.

    I can fix this by changing line 24 to:
    $term = get_term_by( ‘term_taxonomy_id’, $term_id+1 );

    However I’m a bit worried that something will change in a future update and I won’t notice that all my categories are displaying the wrong name! Any idea what could be going on here??

    Thanks for taking the time to write this and your many other snippets by the way – they’re extremely useful and have helped me no end!

    • Bill Erickson says

      That’s incredibly strange. I can’t think of anything that would cause that.

      • Ben Short says

        Ok, I’ve done a bit more digging and I think the issue comes from the fact that to get the term, we’re using the term_taxonomy_id and term_id interchangably:
        get_term_by( ‘term_taxonomy_id’, $term_id );

        However, while the term_taxonomy_id and the term_id are often the same, they’re not in every case. I’ve found that for some reason, on my site they are offset by one.

        This is most likely the cause of the issue Jeremy (above) is having also? Are you able to check if my suspicions are in the right direction…?

        • Jeremy says

          Ben, if you have a copy of the original function which you’ve adjusted/fixed based on your theory, I’d be happy to try it out and see if it fixes my issue! 🙂

          • Ben Short says

            Jeremy, I’ll let you know if I get it working!

            I would have thought only using the $term_id variable in the get_term_by function would have solved the issue:

            if( empty( $value ) ) {
            $term = get_term_by( 'id', $term_id );
            $value = $term->name;
            }

            However, that part of the function doesn’t set the $value variable to anything, it remains empty. I’ll keep you posted…

          • Bill Erickson says

            If you’re using the $term_id you also have to pass the $taxonomy.

            $term = get_term_by( 'id', $term_id, $taxonomy );

            Up until WordPress 4.2, term IDs were only unique for the taxonomy, not site-wide. So you might have two terms with the same ID but in different taxonomies. See taxonomy term splitting in WordPress 4.2 for more details.

  2. Phil Macaulay says

    Hi Bill

    I want to prefix my category with something like ‘Specialists in THE CATEGORY’ as the title of the Category archive. can you suggest how I do this?

    Thanks

    • Bill Erickson says

      Use the code above, but change line 30 from return $value; to return 'Specialists in ' . $value;

  3. swapna says

    Hi Bill, your function was working completely fine when I tested earlier. But after that, I had to remove around 500 unused tags from the website. After deleting these tags, the tag shows title of some other tags. Is it something related to tag id? I am not able to figure out how to rectify this. Please help.

    • Bill Erickson says

      I can’t imagine how that would happen. The titles are stored as metadata based on the $term_id and that should never change. Deleting tags should not affect the term_id’s on existing, non-deleted tags.

    • Errand says

      Had the same problem!
      Fixed it by using $term = get_term($term_id);
      instead of $term = get_term_by( ‘term_taxonomy_id’, $term_id );

  4. Jeremy says

    Hi Bill, this function is working great for me. I’d really love to extend it so that it will default the “Archive Intro Text” field to whatever is written in the “Description” field above it, if “Archive Intro Text” is empty.

    That way, I can leave both “Archive Headline” and “Archive Intro Text” empty, and just have text in the “Name” and “Description” fields, and that text will be used instead – this will save even more time.

    Is it possible to extend your function here to achieve this? I guess it would be more efficient to extend the existing function, rather than creating a new and separate function?

  5. Clara Gonzalez says

    I read all the comments, and either I missed it, or misunderstood, but I’ve looked everywhere for a way to show the Archive Intro Text only on the first page of the category archive. Any idea how to do that?

    Thanks a lot for the help.

  6. Sridhar Katakam says

    Hi Bill,

    Looks like you forgot to update the @param and @return in the Docblock sections in the code snippets.

  7. Khayrattee says

    Hi Bill,
    as of now Oct 2017, with the code above I get the following error. May be an update to the code snippet to be compatible with Genesis v2.5.x ?


    Trying to get property of non-object

    It affects the line:

    $headline = $term->name;

    • Bill Erickson says

      I’ve updated the code in the post. I actually ran into this issue a few weeks ago and forgot to update it here, so thanks for reminding me!

      Since this code only runs on the category/tag/term archive page, there’s no reason to run another query for the term. We can just use get_queried_object().

  8. Andrew says

    When I try this it actually crashes my website.

    I was hoping to make the default title say “Here’s everything filed under [Category]”, but changeable if I input something else in the Archive Headline field. Is there an easy way of adding this?

  9. Hans says

    Thanks Bill, for this useful genesis snippet. Do you know why genesis chose to not use the normal description and category title? Is it just some legacy of sort that hasn’t been changed, or does it aim to solve a problem with standard WordPress?