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 ); |
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 ); |
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.
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;
toreturn 'Specialists in ' . $value;
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 );
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?
Bill Erickson says
I just updated the post to include a function that uses the term’s description for the intro text if empty.
Jeremy says
Thanks so much Bill, that works perfectly!
Is it possible to combine the two into one function? Would that be more efficient, as it would only be making one query? Or not really?
Bill Erickson says
There’s no performance difference having it as two separate functions and it’s easier to read, but here’s what it looks like combined: https://gist.github.com/billerickson/4f8f8e8349e3c4324a52405b53447b7a
Jeremy says
Wonderful, thanks so much! 🙂
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.
Bill Erickson says
Add this to your theme’s functions.php (it removes the intro text on subsequent pages): https://gist.github.com/billerickson/3d42a6e7f89b340821a3273943989066
Sridhar Katakam says
Hi Bill,
Looks like you forgot to update the @param and @return in the Docblock sections in the code snippets.
Bill Erickson says
Updated
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()
.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?
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?