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!

A Duo of New Themes: Motif and Capoverso

Two new free themes from Automattic are now available at WordPress.org.

Long a popular business theme over at WordPress.com, Motif now makes its debut in the WordPress.org directory. A fork of Okay Themes’ Paradigm theme, Motif was completely overhauled by Frank Klein on both the design and code fronts, resulting in a responsive theme well suited to companies and organizations looking for a professional and contemporary web presence.

Motif

Designed by Davide “Folletto” Casali and developed by Caroline Moore, Capoverso is named after an Italian word for the indent in the first line of a paragraph. Davide describes its inspiration:

Capoverso was born as a minimalist typographic theme that could be massively customized with just a couple of images, allowing the expression of the author’s personality in a rich yet simple way. This shows at its best on the homepage: a full-screen image that has large text and the main navigation beneath. Just a couple of tweaks and it’s really your theme.

Capoverso

Two themes, two distinctive personalities: enjoy Motif and Capoverso!

Penscratch

Penscratch, a crisp new theme designed and developed by Caroline Moore, made its debut in the WordPress.org directory this week.

“Penscratch was inspired by a similar portfolio theme, Sketch, which I designed for visual art. I wanted a clean, minimalist theme with a similar look and feel, but tailored to writers.”

With support for Jetpack Site Logos and special styling for pull quotes, Penscratch is worth checking out.

Penscratch screenshot

banner-1544x500

The Power of Eventbrite on WordPress

Eventbrite is the world’s premier event-management service, and we’re happy to announce two new ways to add Eventbrite events to your self-hosted WordPress site!

We’ve offered Eventbrite integration on WordPress.com for a while, with two dedicated themes. While this made getting your events on your WordPress site easier than ever, it wasn’t available to self-hosted users, and you were limited to only the two themes. Both of these issues are solved with new additions to the WordPress.org theme and plugin repositories.


The Eventbrite Multi theme by Voce Communications.

The Eventbrite Multi theme by Voce Communications.

Originally developed by Voce Communications, the Eventbrite themes that have been available on WordPress.com are now in the WordPress.org theme repository, and the plugin that powers them is also available for download. Together, the themes and the plugin provide full-featured Eventbrite integration for single and multiple events, including a calendar view and a widget. Huge thanks to Voce for continuing to support their work in the .org space!


Automattic has also developed an Eventbrite plugin, called Eventbrite API. This plugin is designed to work with any theme, with no explicit support required. It also provides a selection of simple tools that allow theme developers to work with events as easily as custom loops, making Eventbrite theme integrations more fun to build than ever. We’ll have a post next Monday demonstrating how to take advantage of this new plugin in your themes.

Eventbrite and WordPress are a perfect match, and we now have two great plugins for bringing them together. See you at the show!

Mastering the post_class() Function

The post_class() function is one of the many functions provided by WordPress to facilitate theme development. As the name suggests, the post_class() function outputs an HTML class attribute and sets its value to classes related to the post being output.

The correct way to use the function is to add it to the HTML tag that serves as the container for the post content:

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>

The post classes

The number and the name of the classes output by the post_class() function depends on the properties attached to a specific post. Here is an overview of the different possibilities and the contexts in which they are added.

hAtom compliance

WordPress respects the hAtom microformat. Therefore every post has an .hentry class added to it to respect the specification. This class is a great way to target both posts and pages in your CSS.

Post ID

An example of the post ID class might be .post-26. The number at the end of the class corresponds to the ID of this post in the database. As these IDs are unique, this class is a great way to target individual posts in your CSS. Something to keep in mind is that the post ID class starts with .post-, even for pages.

Post type

The post type identifies the type of content that is displayed. By default, WordPress includes posts and pages as content types. This information is output twice, once only the name of the post type (so .post and .page) and once prefixed with type- (so .type-post and .type-page).

When the theme displays a custom post type, the name of the post type that is output corresponds to the first parameter of the register_post_type() function. As an example the classes for the Portfolio Custom Post Type in Jetpack are .jetpack-portfolio and .type-jetpack-portfolio.

Post status

The post status determines how WordPress handles a specific post. Draft posts for example are not displayed on the front end, and private posts are only visible on the front end for users for administrator access. The status is added with status- as a prefix, so .status-published or .status-private for example.

Password protected posts

Posts that are only visible after having entered the post password receive the .post-password-required class.

Sticky

Posts that are marked as sticky receive the .sticky class, but only when they are displayed on the first page of the blog home. On single views or when they are displayed in other types of archives, this class won’t be added.

Post thumbnails

When the activate theme has declared support for post thumbnails, and the post has a featured image set, the .has-post-thumbnail class is added.

Post Formats

The format of the current post prepended with format-. The possible values for the format are aside, audio, chat, gallery, image, link, quote, status and video.

These classes are added independently of whether the theme has declared support for post formats or whether the theme supports the particular format in question. The determining factor for the output of these classes are whether the post type supports post formats. This means that these classes will get added to posts, but not to pages, as pages don’t support post formats out of the box.

Categories and Tags

The categories and tags associated to a particular post will be added with the category- and tag- prefix. The names of the categories and tags are turned into slugs, meaning that they are all lowercase, without special characters and with dashes instead of spaces.

Adding or removing post classes

The post_class() function accepts two optional arguments, $class and $post_id. It is possible to add classes by passing them either as a string or an array as the $class argument.

However, a better alternative is to use the post_class filter. By using a filter, all classes are added and removed in a single place, and the classes that are added aren’t dispersed among the templates files. Additionally this avoids duplication if you want to add classes in different contexts, and it makes it easier for child themes to remove or add their own classes.

Adding classes

Imagine that you want to add specific styles to posts that don’t have a comment yet. How can we do that?

function theme_slug_post_classes( $classes, $class, $post_id ) {
    if ( 0 == get_comments_number( $post_id ) ) {
        $classes[] = 'no-comments';
    }

    return $classes;
}
add_filter( 'post_class', 'theme_slug_post_classes', 10, 3 );

The first thing we need to do is add a custom function to our theme’s functions.php file. In this tutorial, we use a generic prefix; when using this code, please prefix the function correctly.

Our function accepts three parameters ($classes, $class, and $post_id), because these are the variables that WordPress passes through this filter:

  • $classes is an array of classes for the post.
  • $class is a comma separated list of additional classes that may have been added directly via the $class parameter of the post_class() function. If no classes were added, this variable is going to be an empty string.
  • $post_id is an integer and it corresponds to the unique ID of the post.

The $classes array is what we are going to use to add or remove classes. The other two variables provide context for this filter.

In this case, we can use the $post_id variable and pass it to get_comments_number(). This function will then return the number of comments for the post. If there are no comments, we add the .no-comments class to the $classes array.

At the end of the function, we return this array. It is important to do this even when you don’t modify the $classes array. If you don’t return any data or return malformed data, this will break the site.

As we are using the additional variables passed by the post_class filter, we need to add to arguments to the add_filter() call:

  • The 10 at the end corresponds to the priority with which the filter runs. This is the standard priority, and there is no need to change this.
  • The 3 corresponds to the number of variables passed. If you only pass two variables, you need to set this to 2. If you only pass one parameter, this argument and the previous argument can be omitted.

Removing classes

Removing classes works very much the same way. Imagine that we create a child theme for a theme that adds an extra .box class to every post, and we want to remove this.

function theme_slug_post_classes( $classes ) {
    $class_key = array_search( 'box', $classes );

    if ( false !== $class_key ) {
        unset( $classes[ $class_key ] );
    }

    return $classes;
}
add_filter( 'post_class', 'theme_slug_post_classes' );

As $classes is an array, we need to know the key of the array element containing the undesired .box class. This is because the unset() function needs this key in order to remove the corresponding value from the array.

So first we use the array_search() function to look for the box value in our $classes array. The return value of this function is then stored in the $class_key variable.

When the box value isn’t found, $class_key will be set to false, and the $classes array won’t be modified. But when the $class_key contains an integer, this condition will pass and the entry containing the box value will be removed from the $classes array.

In this example, we have removed an extra class. You should avoid removing classes added by WordPress itself, as plugins or user customizations might rely on these classes always being present.

Leveraging post classes in CSS

Now that we have seen how to interact with the post_class() function in PHP, we will look at a few quick tips for how this function can help you write better CSS.

  • Use the core provided classes: When you write your CSS, look at the HTML source code. Often WordPress provides you with the right classes that you can leverage in your CSS. In fact most themes can get by without modifying the post classes at all.
  • Use the body classes: The body_class() function works similar to post_class(). Together they can be used to target any post in any context. If you want to add specific styles to every post or page displayed on the search results page for example, all you need is the .search .hentry selector to target these entries.
  • Use custom parent selectors: When using secondary queries (via WP_Query) for example on a custom page template, developers often run into trouble because there is no easy way to only target the posts output by the secondary query. As with the previous tip, just adding a div element around the output of the loop will allow you style these posts by simply using the parent selector of the container element.

Conclusion

As we have seen post_class() is a very useful function and it will make styling your themes a lot easier if used properly. If you’ve got any questions, let me know in the comments.

Happy theming!

Making Features Available to Themes

I’ve gotten myself into a bit of a problem.

A couple of months ago, we released a new feature called Site Logo on WordPress.com, that allows you to set a logo for your site and have it persist between theme changes. It went over well, and it was decided to roll it into Jetpack for .org users. However, part of that Jetpack integration involved prefixing the template tags used by themes, leaving me with inconsistent function names once we merge Jetpack back to WordPress.com (and for those using the .org Github plugin). It also leaves our premium theme sellers wondering what template tags they should be using moving forward.

I was discussing how to handle the transition with George Stephanis, the Jetpack team lead, and he suggested something I hadn’t considered: have themes just add a hook rather than using template tags when adding features. So rather than theme devs outputting a site logo by adding:

<?php if ( function_exists( 'jetpack_the_site_logo' ) ) jetpack_the_site_logo(); ?>

it could just be:

<?php do_action( 'jetpack_site_logo' ); ?>

I admit it weirds me out: I want to use template tags, the same way I do to output a post title or a featured image, and I imagine people hanging all sorts of strange stuff from it, because, well, it’s a hook. The advantages are clear, though: code behind that hook can be changed and evolve with little concern for theme compatibility, no need for the function_exists() dance, and theme devs have an avenue to alter as much or as little as they choose. In fact, any dev can roll their own original implementation, including a totally different Site Logo plugin.

What do you think? Do you prefer the classic use of template tags, or should we move towards hooks for implementing theme features in Jetpack?

Screen Shot 2014-08-11 at 9.30.46 AM

Prefixing in WordPress Themes

An important best practice when coding a WordPress theme or plugin is correct prefixing.

In this post, we’ll look at:

  1. Why prefixing is needed in PHP.
  2. Why prefixing is needed in WordPress specifically.
  3. How to prefix properly in your code.

Prefixing in PHP

Programming uses the concept of namespaces. It’s an abstract concept that can be explained as a type of container that contains all your code.

In PHP, all functions, classes, interfaces, constants and variables defined outside of functions and methods live by default in the global namespace.

This means that the names you give to these code constructs have to be unique.

Consider this code:

function output() {
    echo 'this';
}

function output() {
    echo 'that';
}

If you run this code (with error reporting enabled), you will get the following error:

Fatal error: Cannot redeclare output() (previously declared in /htdocs/prefixing-post.php:5) in /htdocs/prefixing-post.php:5 on line 10.

Although the functions are not identical, their names are, which creates a conflict. You could simply rename them, and you would be fine:

function output_this() {
    echo 'this';
}

function output_that() {
    echo 'that';
}

While this code runs without errors, the problem is that function names often aren’t unique. Imagine you’re writing software for blogging called Awesome Blogging. In this program you have an output() function that prints the page content.

Everything works fine until you include an external library to handle RSS feeds named Cool RSS. By chance, this code also includes a function named output() to print the RSS feed. Your program is now broken!

This is why it’s an established practice to add a prefix to all functions in a specific piece of code to avoid naming conflicts. In our example above, the first function would be named awesome_blogging_output() and the second one cool_rss_output(). No more conflicts!

You can imagine that prefixing all functions and classes and interfaces as well as constants and variables with global scope can become pretty tedious. This is why PHP introduced a namespaces feature with PHP 5.3.0, which allows you to create your own namespaces without the need for prefixing. Since WordPress currently only requires PHP 5.2.4, though, we can’t yet use this new PHP feature.

Prefixing in WordPress

Prefixing is important in WordPress plugins and themes, because WordPress Core itself does not consistently use prefixes. As of WordPress version 4.0, there are nearly 4950 functions in the Core codebase alone. Some functions and classes in WordPress Core use a wp_ or WP_ prefix, but not all of them. Since this doesn’t even take into account all existing plugins and themes, the potential for a name collision is high.

Prefixing in WordPress Themes

For themes, anything specific to the theme living in the global namespace or stored in the database should be prefixed.

This includes:

  • functions
  • classes
  • actions and filters
  • global variables
  • database entries such as options and post meta

The prefix for these elements should correspond to the theme slug, which in turn should match the theme’s lowercase name, without any spaces or special characters. For functions, classes and global variables, the underscore character should be used. For actions and filters or database entries, the dash character can be used as a separator.

For example, if your theme name is Green Hills, then all functions, classes and global variables would be prefixed with green_hills_. Hooks and database entries would use green-hills- as a prefix.

An Important Best Practice

As we’ve seen in this tutorial, name collisions can result in PHP fatal errors that break entire sites. Proper prefixing lets us avoid these disasters before they happen.

If you have any questions, feel free to leave a comment. Happy theming!