WordPress.org

Make WordPress Core

Opened 7 years ago

Closed 5 years ago

Last modified 5 years ago

#21995 closed feature request (fixed)

(get/the)_archive_title and (get/the)_archive_description functions

Reported by: thomask Owned by: johnbillion
Milestone: 4.1 Priority: normal
Severity: normal Version: 4.1
Component: Themes Keywords: has-patch twenty-fifteen
Focuses: template Cc:

Description

Current theme archive got problem with complexity - archive template is used for taxonomy, category, tag, author, date and custom post types archives and every type of archive got special function for showing title and special function for showing description.

So now theme developers fight with two evils - one very big archive.php file with a lot of conditions, or tons of separate simple .php files for each archive type. See #21951 for example.

Other problem of current solution is that templates are not future-proof - when new archive types are added, archive.php must be rewritten.

My idea is to create 2 simple functions (+ 2 echoing)
get_archive_title + the_archive_title
get_archive_description + the_archive_description

in those function would be all the complexity, which is now in the template, plus the filter, so something like

function get_archive_title() {
if ( is_day() ) {
	$title = sprintf( __( 'Daily Archives: %s' ), '<span>' . get_the_date() . '</span>' );
} elseif ( is_month() ) {
	$title = sprintf( __( 'Monthly Archives: %s' ), '<span>' . get_the_date( _x( 'F Y', 'monthly archives date format' ) ) . '</span>' );
} elseif ( is_year() ) {
	$title = sprintf( __( 'Yearly Archives: %s' ), '<span>' . get_the_date( _x( 'Y', 'yearly archives date format' ) ) . '</span>' );
} elseif ( is_tag() ) {
	$title = sprintf( __( 'Tag Archives: %s' ), '<span>' . single_tag_title( '', false ) . '</span>' );
} elseif ( is_category() ) {
	$title = sprintf( __( 'Category Archives: %s' ), '<span>' . single_cat_title( '', false ) . '</span>' );
} elseif ( is_post_type_archive() ) {
	$title =  sprintf( __( 'Archives: %s' ), '<span>' . post_type_archive_title( '', false ) . '</span>' );
} else {
	$title = _e( 'Blog Archives' );
}
return ( add_filter ( 'get_archive_title', $title ) );
}

(imo it could be a bit more complex, so that we could add a param to this function for simple rewritting the title for some particular type without filtering whole output)

Finally the archive template would be as simple as

<header class="archive-header">
<h1 class="archive-title"><?php the_archive_title() ?></h1>

<div class="archive-meta"><?php the_archive_description ?></div>

</header><!-- .archive-header -->

this way we will get all we need

  1. one archive file
  2. very short file without any conditions
  3. easy to filter the output
  4. future-proof as when adding new wp archive type, the function would be updated

Of course, for backwards compatibility of current themes, this function can be copied to the theme functions.php as well with !if (function_exist(
'get_archive_title'))

Attachments (9)

21995.diff (2.4 KB) - added by DrewAPicture 7 years ago.
Suggested first-run
21995.2.diff (2.8 KB) - added by DrewAPicture 7 years ago.
Adds $container param, improved phpdocs
21995.3.diff (2.9 KB) - added by DrewAPicture 7 years ago.
Fix specifier typo in $after, allow bypassing $container
21995.4.diff (3.0 KB) - added by DrewAPicture 7 years ago.
Taxonomy singular label w/ translator note
21995.5.diff (3.1 KB) - added by DrewAPicture 7 years ago.
21995.6.diff (3.1 KB) - added by DrewAPicture 7 years ago.
21995.7.diff (3.5 KB) - added by obenland 5 years ago.
21995.8.diff (3.8 KB) - added by obenland 5 years ago.
21995.9.diff (4.1 KB) - added by obenland 5 years ago.
Revised Audio title, context for post format titles.

Download all attachments as: .zip

Change History (64)

#1 @SergeyBiryukov
7 years ago

  • Component changed from General to Template

#2 @knutsp
7 years ago

  • Cc knut@… added

+1 (adds two new functions that are really missing)

@DrewAPicture
7 years ago

Suggested first-run

#3 @DrewAPicture
7 years ago

  • Cc xoodrew@… added
  • Keywords has-patch dev-feedback added

I'm kind of on the fence about this. You'd write almost as much code filtering the thing to suit your taste as you would just using the conditionals. On the other hand, having them all wrapped up like this would make for a neater archive.php.

Attached a first-run patch.

#4 @greenshady
7 years ago

+1 for this. This is one of the things I hate most about making themes.

One thing I'd like to see done in addition to this is single_author_title() and author_description() functions.

#5 @greenshady
7 years ago

  • Cc justin@… added

#6 @thee17
7 years ago

I like the idea of this in core. 90% of the Themes in the repository seem to have a version of the conditionals copy/pasted in the archive.php unmodified from "Default/Kubrick", "Twenty Ten", or "Twenty Eleven". It is also the type of function that does not hinder a theme from using the old method either if it chooses.

#7 @thee17
7 years ago

  • Cc charles@… added

#8 @emzo
7 years ago

  • Cc wordpress@… added

#9 @lightningspirit
7 years ago

  • Cc lightningspirit@… added

#10 @toscho
7 years ago

  • Cc info@… added

#11 @nacin
7 years ago

  • Milestone changed from Awaiting Review to 3.6

#12 @BandonRandon
7 years ago

  • Cc BandonRandon added

+1, Yes please!

#13 follow-up: @mdgl
7 years ago

I like the idea of this and believe we should in general be doing more to address the needs of theme/plugin developers. I would like however to make a few comments on the first-cut patch from DrewAPicture:

1) The code probably intends to make use of sprintf() rather than printf().

2) Function the_archive_title() is starting to look very similar to wp_title() and I wonder whether there is an opportunity to generalise and/or share more code between these functions (e.g. create the_page_title() applying to any form of page not just archives and merge code with wp_title()). See also comment:4.

3) For custom taxonomies, rather than just printing "Taxonomy Archives" we should probably refer to the name of the particular taxonomy as already happens with category and post_tag, so for example:

} elseif ( is_tax() ) {
      $term = get_queried_object();
      $tax = get_taxonomy( $term->taxonomy );
      $title = sprintf( __( '%1$s Archives: %2$s' ), '<span>' . $tax->labels->singular_name . '</span>', '<span>' . single_term_title( '', false ) . '</span>' ); 
}

A moot point is then whether the <span> elements would need to be distinguished for styling.

#14 @thee17
7 years ago

Or replace the <span> and </span> with a parameter that defaults to <span> and </span> but easily overridable to other HTML5 tags or styling.

@DrewAPicture
7 years ago

Adds $container param, improved phpdocs

#15 in reply to: ↑ 13 ; follow-up: @DrewAPicture
7 years ago

21995.2.diff adds a $container param defaulting to span. Also improved the phpdocs and changed the printfs to sprintfs in light of the $display bool.

Replying to mdgl:

3) For custom taxonomies, rather than just printing "Taxonomy Archives" we should probably refer to the name of the particular taxonomy as already happens with category and post_tag.

I'm going to hold off on customizing the Taxonomy Archives text until we have some feedback from folks like @pavelevap, @SergeyBiryukov or @dd32. Of late there's been reticence to leverage the taxonomy labels because of lack of control over the context.

I can see adding a new label for taxonomy archives but that also may be off the table.

#16 follow-up: @thee17
7 years ago

There is something wrong, I am returning

Category Archives: <span>General</0>

with the_archive_title() perhaps it would be nice to have the option to disable the tags or do something similar.

#17 in reply to: ↑ 16 @mdgl
7 years ago

Replying to thee17:

There is something wrong, I am returning

Category Archives: <span>General</0>

with the_archive_title() perhaps it would be nice to have the option to disable the tags or do something similar.

There is just a small typo in the latest patch:

$after = sprintf( '</%x>', $container );

which should of course use the %s type specifier rather than %x. In fact, I suspect that if $container is empty the code should leave both $before and $after completely empty as well.

#18 @DrewAPicture
7 years ago

Replying to mdgl:

There is just a small typo in the latest patch:

$after = sprintf( '</%x>', $container );

which should of course use the %s type specifier rather than %x.

Done in 21995.3.diff

In fact, I suspect that if $container is empty the code should leave both $before and $after completely empty as well.

It is now. Defaults to span, but if you specify $container as empty it'll output nothing.

@DrewAPicture
7 years ago

Fix specifier typo in $after, allow bypassing $container

#19 @thee17
7 years ago

it works great now, sure reduces a lot of code in my theme.

#20 in reply to: ↑ 15 @SergeyBiryukov
7 years ago

Replying to DrewAPicture:

Replying to mdgl:

3) For custom taxonomies, rather than just printing "Taxonomy Archives" we should probably refer to the name of the particular taxonomy as already happens with category and post_tag.

I'm going to hold off on customizing the Taxonomy Archives text until we have some feedback from folks like @pavelevap, @SergeyBiryukov or @dd32. Of late there's been reticence to leverage the taxonomy labels because of lack of control over the context.

The closest thing that comes to mind is cattitle argument in feed_links_extra():
http://core.trac.wordpress.org/browser/tags/3.5.1/wp-includes/general-template.php#L1626

It's '%1$s %2$s %3$s Category Feed', which seems to work. posttypetitle, on the other hand, is just '%1$s %2$s %3$s Feed', which maybe not be ideal for i18n, but there's a comment above it where all the placeholders are explained, so that translators could figure it out and translate accordingly.

So I guess '%1$s Archives: %2$s' might work too for a custom taxonomy archive title, as long as there's an explanation for the placeholders.

@DrewAPicture
7 years ago

Taxonomy singular label w/ translator note

#21 @DrewAPicture
7 years ago

21995.4.diff adds the taxonomy singular name label when is_tax().

I'm not a huge fan of having to add curly braces just for that one multi-line condition. On the other hand, I felt like doing this:

$title = sprintf( __( '%1$s Archives: %2$s' ), get_taxonomy( get_queried_object()->taxonomy )->labels->singular_name, $before . single_term_title( '', false ) . $after );

was a bit too clever just to keep it on one line.

@DrewAPicture
7 years ago

#22 @DrewAPicture
7 years ago

After a conversation with @helen this morning, opted to test if $term->taxonomy isset before proceeding in 21995.5.diff

@DrewAPicture
7 years ago

#23 follow-up: @DrewAPicture
7 years ago

Based on further review of other uses of get_queried_object(), I'm going to go without the check in 21995.6.diff

#24 in reply to: ↑ 23 @mdgl
7 years ago

Replying to DrewAPicture:

Based on further review of other uses of get_queried_object(), I'm going to go without the check in 21995.6.diff

Ah, yes the "what exactly is the queried object" problem!! I believe this can be a bit hairy in the presence of "complex" queries, and I am sure there are other tickets on this very topic, but somehow, if is_tax() returns true you need to be able to rely on the object being a (custom) taxonomy. Similarly for the other is_xxx() functions. Anything else results in too much madness!!

#25 @DrewAPicture
6 years ago

  • Milestone changed from 3.6 to Future Release

#26 @nacin
6 years ago

  • Component changed from Template to Themes
  • Focuses template added

@obenland
5 years ago

#27 @obenland
5 years ago

  • Keywords dev-feedback removed
  • Milestone changed from Future Release to 4.1
  • Version set to trunk

In 21995.7.diff:

  • Simplify function parameters, taking inspiration from the_title().
  • Remove redundant "archives" from translation strings.
  • Split archive_title in a returning "get_" and a displaying the_.
  • Add the_archive_description() as an echoing pendant to term_description().
  • Adds post format support.

There are two filters in this proposal, get_archive_title and the_archive_description. We could add a the_archive_title filter for similarity to the description function, but it would just filter the value of get_archive_title.

The span wrappers were introduced in Twenty Eleven and then copied by a lot of other themes. They are hardly ever used, by far not by a majority, so I think we shouldn't add that complexity.

Twenty Fifteen would benefit a great deal from this patch (#29799).

#28 @obenland
5 years ago

  • Keywords twenty-fifteen added

Tagging with twenty-fifteen to keep track of it.

#29 @Frank Klein
5 years ago

Latest patch looks good to me.

#30 @chrisvanpatten
5 years ago

Random question: why isn't the function name get_the_archive_title? We finally got get_the_permalink in core (3.9 I think?) to match the other core templating functions (get_the_title, get_the_ID, get_the_content, get_the_post_thumbnail, etc.) - shouldn't that convention be mirrored for new functions?

As a side note - should that convention be documented somewhere, so it's followed for additional new functions?

Last edited 5 years ago by chrisvanpatten (previous) (diff)

#31 @obenland
5 years ago

Yes, this would be a good opportunity to strengthen that.

#32 @ocean90
5 years ago

There is no need to use esc_html__() here. We trust translations.

I think we should have get_the_archive_description() too which does return apply_filters( 'the_archive_description', term_description() );.

#33 @obenland
5 years ago

I updated the patch with the recent feedback.

@obenland
5 years ago

#34 @ocean90
5 years ago

  • Keywords commit added

21995.8.diff looks good.

This ticket was mentioned in Slack in #core by obenland. View the logs.


5 years ago

#36 follow-up: @johnbillion
5 years ago

This looks good. Two small issues:

  1. Should we use "Audio" instead of "Audios"?
  2. Do we need translator context on any of the post format archive titles?

This ticket was mentioned in Slack in #core by obenland. View the logs.


5 years ago

#38 in reply to: ↑ 36 @siobhan
5 years ago

Replying to johnbillion:

This looks good. Two small issues:

  1. Should we use "Audio" instead of "Audios"?
  2. Do we need translator context on any of the post format archive titles?

We should use Audio. Audio is normally considered uncountable. It can refer to all of the audio recordings on your site. You can use "audios" but it's uncommon. "Audio Recordings" or "Audio Clips" would be more common for the plural form.

This is a good explanation: http://english.stackexchange.com/questions/40429/if-i-can-say-videos-can-i-also-say-audios (see the second answer, not the first :) )

@obenland
5 years ago

Revised Audio title, context for post format titles.

#39 @obenland
5 years ago

21995.9.diff includes a revised Audio title and context for post format titles.

#40 @johnbillion
5 years ago

  • Owner set to johnbillion
  • Resolution set to fixed
  • Status changed from new to closed

In 30223:

Introduce some new template functions for archive titles and descriptions:

  • get_the_archive_title() and the_archive_title() for returning/displaying the title of the current term, date, post type, post format, or author archive.
  • get_the_archive_description() and the_archive_description() for returning/displaying the description associated with the current term archive.

Fixes #21995
Props obenland, DrewAPicture

#41 @DrewAPicture
5 years ago

In 30224:

Cross reference get_the_archive_title() and get_the_archive_description() in the inline documentation for their corresponding template tags.

Also define the default values for $before and $after in the template tag documentation.

See [30223]. See #21995.

#42 follow-up: @McGuive7
5 years ago

I know this just went through, but I have a suggestion for improvement. . .

Some of the generated titles have essentially hardcoded prefixes within them. For example: __( 'Category: %s' ) and __( 'Author: %s' ).

Since this text is prepended to the title before it is is passed to the get_the_archive_title filter, it now necessitates some more complicated string replacement to remove/change the prefix, right? My suggestion is to simply assign these "prefixes" to a $prefix variable, which is either filterable, or added via the get_the_archive_title filter so that it can easily be unhooked.

Anyone else think this is worth doing? I ask because I've often needed to change these prefixes as per client requests to things like the plural label of a custom post type (e.g. Cars: ) or a more intuitive title for a date archive (e.g. Archive for May, 12 2014).

Happy to create a patch if others aren't opposed to this change. Thoughts?

#43 in reply to: ↑ 42 ; follow-up: @afercia
5 years ago

Replying to McGuive7:

Anyone else think this is worth doing?

I agree. This is basically hardcoding something that before was very easy to change in a theme.
All these titles will be mostly used as the main heading in a page, the most important piece of information for:

  • assistive technologies
  • SEO
  • machine readability

Moreover, please don't think just in English. Other languages may need to change the titles and provide more context; trying to handle this with the translation sometimes is not enough.
Some examples:

  • Year: 2014
  • Audio
  • Asides

read out of context, they don't give enough information about the page. Is this a single post title? Is this a generic list? Is a chronological archive? Please don't think just visually.
For example, imagine you're a screen reader user:

  • you follow a link from some external site
  • you land on one of these archive pages
  • first thing you do: you try to get the h1 of the page and what you get is...

"Audio".

As I see it, as soon as theme authors will start using these new template tags, they will try to find a way to change that hardcoded stuff.
Please, please, consider to reopen :)

#44 in reply to: ↑ 43 @Monika
5 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

Replying to afercia:

Replying to McGuive7:

Anyone else think this is worth doing?

I agree. This is basically hardcoding something that before was very easy to change in a theme.
All these titles will be mostly used as the main heading in a page, the most important piece of information for:

  • assistive technologies
  • SEO
  • machine readability

Moreover, please don't think just in English. Other languages may need to change the titles and provide more context; trying to handle this with the translation sometimes is not enough.
Some examples:

  • Year: 2014
  • Audio
  • Asides

read out of context, they don't give enough information about the page. Is this a single post title? Is this a generic list? Is a chronological archive? Please don't think just visually.
For example, imagine you're a screen reader user:

  • you follow a link from some external site
  • you land on one of these archive pages
  • first thing you do: you try to get the h1 of the page and what you get is...

"Audio".

As I see it, as soon as theme authors will start using these new template tags, they will try to find a way to change that hardcoded stuff.
Please, please, consider to reopen :)

I agree to 1000000%

#45 follow-up: @Frank Klein
5 years ago

Since this text is prepended to the title before it is is passed to the get_the_archive_title filter, it now necessitates some more complicated string replacement to remove/change the prefix, right?

The filter doesn't restrict you to doing string replacement, you can create your own string with whatever you want and return that. Using a prefix variable is not only not needed, because of the filter, but also very difficult to use, as this would have to be an array with keys for the different contexts.

So the filter allows you to do everything you could do with that variable you propose, and the filter is way easier to use and in line with how WordPress handles similar cases.

Moreover, please don't think just in English. Other languages may need to change the titles and provide more context; trying to handle this with the translation sometimes is not enough.

The current code already handles context via the _x() function. I think we should leave it up to the translators to see whether they can make this work for their language or not. We can always reopen when that need arises, which I doubt.

read out of context, they don't give enough information about the page. Is this a single post title? Is this a generic list? Is a chronological archive? Please don't think just visually.

Considering that this code comes from Underscores, an open source project that gets reviewed regularly by contributors with accessibility experience, I don't think this is a problem. Also, you can always filter if you want to change the implementation in your theme.

Proposing to close.

#46 @McGuive7
5 years ago

Thanks for the response Frank, very helpful. And I totally agree in regards to translation - I see all the important pieces in place already. My question is more around filtering the prefix specifically. At present, for someone to filter just the prefix, they actually have to filter the entire title, which requires essentially duplicating whatever function is being used to generate the non-prefix part of the title. Not super hard, but also not my favorite choice for two reasons:

  1. It requires users to dig into core code (or the codex) to reproduce functionality when really they might just want to remove the word "Archives:".
  1. The present method smushes together what I see as two separate pieces of content: a prefix and an actual title. To me, the prefix and the title in this situation are much like a label and an input in a form. Or an icon and a link that sit next to each other. One is primary and one is secondary. You could also say one is more ornamental, and more is more fundamental. Most coding and design folks agree that the two should be separated, right? Same seems true in this case.

So, what do I propose? Well here's a look - would love to know why this would or wouldn't make sense:

Old code style (consolidated for example):

if ( is_category() ) { 
	$title = sprintf( __( 'Category: %s' ), single_cat_title( '', false ) ); 
}

return apply_filters( 'get_the_archive_title', $title );

Proposed update:

$prefix = '';

if ( is_category() ) { 
	$prefix = __( 'Category:' );
	$title = single_cat_title( '', false ); 
}

// Add blank space after prefix as needed
$prefix = $prefix ? $prefix . ' ' : '';

// Filter prefix
$prefix = apply_filters( 'get_the_archive_prefix', $prefix );

// Output prefix and title
return $prefix . apply_filters( 'get_the_archive_title', $title );

You make mention of needing an array of prefix values for filtering, but this method doesn't seem to require that - unless I'm missing something. Sure it's a bit of extra code, but it adds a filter that I know I've wished was there a number of times. It's so much handier to just filter the prefix than have to override the entire output, right?

As for what you said about Underscores being reviewed regularly by experienced folks - I fully agree. AND, isn't that what we're doing right now? I think it's conversations like these that contribute to some of Underscores continual improvements.

Thanks! Would love to hear more on why this is/isn't a good solution.

#47 @chrisvanpatten
5 years ago

(Caveat: I may be missing something essential.)

Giving the prefix its own filter seems (to me) to be less flexible, not more flexible. It assumes you'll always want the prefix to be a prefix.

What if you want to make the "prefix" a suffix instead (e.g. "Pizza [Category]" or something)? You'd have to somehow save the prefix (in a global or something? ew.) and replace it with an empty string, then append the prefix you previously saved to the end of the full archive title in a separate function.

Sure, doing regex parsing and such is a bit annoying (okay, a lot annoying) but separating it out and concating the prefix (as in the example above) makes assumptions about text order that might not always be true.

(Again, unless I'm missing something super obvious, which I very well might be.)

#48 @chrisvanpatten
5 years ago

Random (and potentially dumb/ill-informed) idea: what if the prefix were set in a separate variable within the function—as @McGuive7 proposed—but instead of giving it a dedicated filter it's just passed into apply_filters as an additional parameter? That way if you wanted to remove the prefix for some reason, you could much more easily do this:

function my_remove_prefix( $title, $prefix ) {
    $just_the_title = str_replace( $prefix, '', $title );
    return $just_the_title;
}

add_filter( 'get_the_archive_title', 'my_remove_prefix', 10, 2 );

#49 @ocean90
5 years ago

$prefix . apply_filters( 'get_the_archive_title', $title ); doesn't work for RTL languages.

And I don't see the need to make the prefix itself filterable. get_the_archive_title would be enough:

add_filter( 'get_the_archive_title', function( $title ) {

	if ( is_author() ) {
		$title = get_the_author();
	} elseif ( is_tax( 'post_format', 'post-format-audio' ) ) {
		$title = _( 'Posts about Audio', 'foo' );
	}

	return $title;
} );

#50 @obenland
5 years ago

Yes, making the prefix filterable wouldn't make a big difference. Developers would still have to check for which archive page they're on before making a change, due to the nature of the template hierarchy.

Just replace the entire title like ocean90 suggested—retrieving the title of the queried object again should be no concern.

#51 @McGuive7
5 years ago

Cool, I'm convinced. Thanks y'all. And Mickey learns something new. Check.

#52 in reply to: ↑ 45 @afercia
5 years ago

Replying to Frank Klein:

Moreover, please don't think just in English. Other languages may need to change the titles and provide more context; trying to handle this with the translation sometimes is not enough.

The current code already handles context via the _x() function. I think we should leave it up to the translators to see whether they can make this work for their language or not. We can always reopen when that need arises, which I doubt.

read out of context, they don't give enough information about the page. Is this a single post title? Is this a generic list? Is a chronological archive? Please don't think just visually.

Considering that this code comes from Underscores, an open source project that gets reviewed regularly by contributors with accessibility experience, I don't think this is a problem.

hi Frank, just to clarify: with "context" I was not referring to translation tools like the various x(). When speaking about accessibility we often use the word "context" referring to the information conveyed by elements in relation to the "surrounding" information. Every link, heading, etc. should convey a clear information even when read out of context.
For example, Assistive Technologies provide tools to extrapolate from a page list of links, list of headings, landmarks, etc. Information conveyed by such elements should be clear even when read in such lists. More or less, it's the same, well known, long debated, issue of the "click here" link. To give you an idea, see in the screenshot below what NVDA can offer extrapolating information from a page. Screenshot refers to the "Audio" archive in Twenty Fifteen.

https://cldup.com/aqug1a04Dq.png

#53 @obenland
5 years ago

  • Keywords commit removed
  • Resolution set to fixed
  • Status changed from reopened to closed

#54 @nacin
5 years ago

In 30854:

Avoid repeatedly calling is_tax( 'post_format', '...' ) in get_the_archive_title().

see #21995.

#55 @johnbillion
5 years ago

In 30864:

Avoid repeatedly calling is_tax( 'post_format', '...' ) in get_the_archive_title().

Merges [30854] to the 4.1 branch.

See #21995.

Note: See TracTickets for help on using tickets.