What’s new in WordPress 4.1 for Theme Developers?

WordPress 4.1 has been a long-awaited release for theme developers. Not only does this version ship with the awesome Twenty Fifteen theme, but also with a number of new functions and features that make theme development faster and easier. In this post, we’ll have a look at these new features and show you how to use them in your themes.

Auto-generated Title Tags

Until the release of WordPress 4.1, each theme contained its own implementation of the <title> tag. This code often varied from theme to theme, making it difficult for plugins — for example SEO plugins — to customize the content of the title tags.

The new, recommended approach is to leverage the add_theme_support() function by declaring support for title-tag:

function theme_slug_setup() {
   add_theme_support( 'title-tag' );
}
add_action( 'after_setup_theme', 'theme_slug_setup' );

By declaring theme support, you indicate to WordPress that the title tag should be auto-generated. This is done using the private function _wp_render_title_tag(), which is hooked to wp_head. You can still use the wp_title filter to customize the output of the new auto-generated title tags.

Navigation and Pagination

While WordPress has included functions to generate navigation links between posts or pages of posts for a while, each theme used these functions with different markup and text. WordPress 4.1 provides template tags that output the entire navigation for you.

This allows theme developers to focus on the most important element: styling. Additionally, when using the default strings, these are automatically translated in your theme, because the translations for these strings are included in Core.

Post Navigation

The post navigation functions, the_post_navigation() and get_the_post_navigation(), output a set of links to the previous and next posts. These functions are used on single post views (like single.php).

These functions accept an array arguments:

  • prev_text: Text of the link to the previous post. Defaults to the post title.
  • next_text: Text of the link to the next post. Defaults to the post title.
  • screen_reader_text: Text meant for screen readers. Defaults to “Post navigation”.

Sample HTML output:

<nav class="navigation post-navigation" role="navigation">
    <h2 class="screen-reader-text">Post navigation</h2>
    <div class="nav-links">
        <div class="nav-previous"><a href="http://website.com/beautiful-sea" rel="prev">Beautiful Sea</a></div>
        <div class="nav-next"><a href="http://website.com/spring-landscape" rel="next">Spring Landscape</a></div>
    </div>
</nav>

Posts Navigation

The posts navigation functions, the_posts_navigation() and get_the_posts_navigation(), output a set of links to the previous and next pages of posts. These functions are used for post listings (like index.php) or archives (like archives.php).

These functions accept an array of arguments:

  • prev_text: Text of the link to the previous set of posts. Defaults to “Older posts”.
  • next_text: Text of the link to the next set of posts. Defaults to “Newer posts”.
  • screen_reader_text: Text meant for screen readers. Defaults to “Posts navigation”.

Sample HTML output:

<nav class="navigation posts-navigation" role="navigation">
    <h2 class="screen-reader-text">Posts navigation</h2>
    <div class="nav-links"><div class="nav-previous"><a href="http://website.com/page/3">Older posts</a></div><div class="nav-next"><a href="http://website.com/">Newer posts</a></div></div>
</nav>

Post Pagination

The posts pagination functions, the_posts_pagination() and get_the_posts_pagination(), output a set of page numbers with links to the previous and next pages of posts. These functions are used for post listings (like index.php) or archives (like archives.php).

These functions accept an array of arguments:

  • mid_size: How many page numbers to display to either side of the current page. Defaults to 1.
  • prev_text: Text of the link to the next set of posts. Defaults to “Previous”.
  • next_text: Text of the link to the next set of posts. Defaults to “Next”.
  • screen_reader_text: Text meant for screen readers. Defaults to “Posts navigation”.

Sample HTML output:

<nav class="navigation pagination" role="navigation">
    <h2 class="screen-reader-text">Posts navigation</h2>
    <div class="nav-links"><a class="prev page-numbers" href="http://website.com/page/3/">Previous</a>
        <a class="page-numbers" href="http://example.com/">1</a>
        <span class="page-numbers dots">…</span>
        <a class="page-numbers" href="http://example.com/page/3/">3</a>
        <span class="page-numbers current">4</span>
        <a class="page-numbers" href="http://example.com/page/5/">5</a>
        <a class="page-numbers" href="http://example.com/page/6/">6</a>
        <a class="next page-numbers" href="http://example.com/page/5/">Next</a>
   </div>
</nav>

Archives

Archives are an important feature in WordPress. By default, WordPress supports taxonomy (categories, tags and post formats), author, and date (year, month, day) archives.

Two of the default taxonomies, categories and tags, support archive descriptions. This feature allows users to add descriptions for each term in these taxonomies.

It has become a best practice among theme developers to display these descriptions on archive pages, along with a contextual archive title. WordPress 4.1 introduces two new template tags to help with this.

Archive titles

The the_archive_title() and get_the_archive_title() functions display the title of an archive, as in the term or the date, with a contextual text prefix. The prefix depends on the type of archive:

  • “Category: ” for category archives.
  • “Tag: ” for tag archives.
  • “Author: ” for author archives.
  • “Year: “, “Month: ” and “Day: ” for date archives.
  • “Asides: “, “Galleries: “, “Images: “, “Videos: “, “Quotes: “, “Links :”, “Statuses: “, “Audio: ” and “Chats: ” for post format archives.
  • “Archives: ” for custom post type archives.
  • Singular taxonomy name for custom taxonomy archives.

Theme developers that want to modify the default strings can use the get_the_archive_title filter to do so.

The the_archive_title() accepts two arguments, $before and $after, that can be used to add additional text or HTML before or after the archive title.

Archive description

The the_archive_description() and get_the_archive_description() functions output the description of a taxonomy. These functions work with categories and tags as well as custom taxonomies.

The the_archive_description() template tag accepts two arguments, $before and $after, that can be used to add additional text or HTML before or after the term description.

Screen Reader Text

When using these new template tags, you might be surprised by extra text being displayed.

This is because these functions include text that provide contextual information for screen readers. This is a very important accessibility feature and it does not impact your theme’s design, as you can remove these elements while still keeping them accessible for screen readers with the following styles for the .screen-reader-text class:

.screen-reader-text {
    clip: rect(1px, 1px, 1px, 1px);
    position: absolute !important;
    height: 1px;
    width: 1px;
    overflow: hidden;
}

Deprecated Admin Screens

WordPress 4.1 also deprecates the Background and Header screens in the admin. When users click on these links, they are redirected to the Customizer, where they can make changes with a visual preview of the results.

When adding theme support for the custom background feature, you will no longer have to implement callback functions for the admin-head-callback and admin-preview-callback arguments of add_theme_support( 'custom-background' ).

Want to know more?

You might agree these new functions are awesome, but you might be unsure how to use them. I’d encourage you to have a look at the _s (Underscores) starter theme on Github. It is up to date with all the new functions added in 4.1 and provides backwards compatibility for older versions of WordPress.  You can also look at the source code of Twenty Fifteen, which leverages all these new functions.

Happy theming!

18 responses

  1. You can still use the wp_title filter to customize the output of the new auto-generated title tags.

    In most cases this should not be necessary. If a theme declares support, the adjustments most default themes (and _s) made are applied out of the box.

    This is especially noteworthy because “Title Tag” is only using wp_title() temporarily and will move away from it soon.

    1. In the current version of _s, is there an example of making adjustments to the title that will be “applied out of the box”? All I can see (in extras.php) is a filter for wp_title, along with the shim for backwards compatibility.

      Is there a method that I can use now to modify the title, without dumping wp_title back in and filtering it?

      And it may not be necessary in most cases, but it’s definitely a requirement in many cases: I always use a custom separator and create more human-readable and less WordPress-y titles for archives and search results.

      1. Fränk Klein Avatar
        Fränk Klein

        As mentioned, you still can use the wp_title filter to adapt the output of the auto-generated titles.

        1. As mentioned, you still can use the wp_title filter to adapt the output of the auto-generated titles.

          Yes. Let me try to rephrase my question: is there now a new, better, cleaner, more direct or more forward-compatible way to modify the output for the title element? Something I can implement now, and that will play nice with plugins down the line?

          As of now, I am filtering wp_title as before – however, the function suggested in the Codex doesn’t do the same things anymore. For example, instead of having the option to add the site name to the title tag, I now have to find a way to remove it if I don’t want it?

          And how would I now pass a custom separator to the title tag? Do I somehow hook into _wp_render_title_tag(), or do I have to override _wp_render_title_tag() and send my own function to wp_head? And could that not lead to the same problems with plugins?

          Thanks – I know this is not a support forum, I just can’t find any documentation about this…

        2. Fränk Klein Avatar
          Fränk Klein

          Thanks for providing more details concerning your question.

          So as Konstantin pointed out, the forward compatible solution would be to use the auto-generated title tags without any filtering. This is because the objective of this new feature is to let the user determine the structure of the titles.

          Still even if the new auto-generated title tags now output a different title structure, the wp_title filter still is the best way to modify the title output. I’d recommend that you consult the source code of the wp_title() function.

          This should make things a lot clearer than relying on the Codex.

  2. Good article. You accidentally write two “Post Navigation” sections btw.

    1. Fränk Klein Avatar
      Fränk Klein

      Thanks!

      There are two different sections, there is a Post Navigation section and a Posts Navigation section. That little “s” makes all the difference. 😉

  3. For the Navigation items how can you exclude post id’s

    1. Fränk Klein Avatar
      Fränk Klein

      I’m unsure about what the request here is, but the navigation function are template tags that use other functions. So you’d have to look into those if you want to filter the data they use.

  4. kevinhaig Avatar

    For the navigation it would be nice to pass a 4th argument which would be a comma delimited list of id’s to exclude from the navigation

  5. How to using those functions backward compatible with WordPress old version?

    1. Fränk Klein Avatar
      Fränk Klein

      The _s starter theme has all the necessary code for backwards compatibility: https://github.com/Automattic/_s

  6. Is there a reason the the_archive_description() function outputs P tags?

    None of the similar functions (the_title for example), output any type of tag.

    1. Fränk Klein Avatar
      Fränk Klein

      By default the_archive_description() function does not output any HTML tags. If you use the $before or $after arguments, then those tags will be output when an archive description exists.

      1. It outputs P tags inside the $before and $after. Here is a screenshot from a fresh WP install using a fresh version of _s.

        http://prntscr.com/6607ws

        Is this a bug?

  7. It outputs P tags inside the $before and $after. Here is a screenshot from a fresh WP install using a fresh version of _s.

    http://prntscr.com/6607ws

    Is this a bug?

    1. Fränk Klein Avatar
      Fränk Klein

      No, this is not a bug. The <p> tags are added by a default filter, see wp-includes/default-filters.php.

      If you want to remove the <p> tags, you can use the get_the_archive_description filter.