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>

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>

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>


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!

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.


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.


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!

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!


Why Bootstrap is a bad fit for WordPress Themes

Since its release in 2011, Bootstrap has quickly become the most popular front-end framework on Github. This popularity also has an impact on the world of WordPress themes, with authors using the framework during development or even releasing themes that feature Bootstrap as unique selling point.

This is surprising, because Bootstrap is not a great fit for WordPress theme development.

Bootstrap is the wrong tool for the job

Bootstrap was created at Twitter as a tool for back-end developers to easily create interfaces for their applications. Before Bootstrap, various other libraries were used, which resulted in inconsistent and difficult to maintain interfaces.

So Bootstrap was created with a precise goal in mind, and it continues to develop according to this initial vision for the project. It was created so that developers could focus on back-end code and quickly iterate without having to worry about the front-end.

This is why it’s the wrong tool for a WordPress theme: the front-end, or how the site looks with the theme activated, is all that counts.

Bootstrap does not do things the WordPress Way

WordPress facilitates theme development by providing a set of functions to be used in template files. By leveraging the HTML output of these functions, developers can write efficient and clean code that works with a variety of content.

Bootstrap on the other hand has its own approach to how the HTML is structured, and it does not fit well with what WordPress provides by default.

As such, developers have to take extra steps and write additional code to modify WordPress’ behavior to the fit how the framework works. A good example for this are navigation menus. Instead of using the output of wp_nav_menu(), developers have to write Custom Walker classes that change the HTML output by the function so that the Bootstrap CSS and Javascript can be used.

This approach results in more code and as such is less efficient, results in more maintenance and development time and also does not benefit from the enhancements made to the Core functions.

Bootstrap is bloated

Framework code can never be as efficient as code written for a specific purpose, since frameworks build up from general cases to more specific cases and add bloat in the process. Often multiple CSS classes need to be added to HTML elements to achieve a desired visual result, along with the necessary CSS.

What adds to this problem is that often times, not only the CSS code necessary for the theme’s design is packaged, but the entire framework code.

Bootstrap does not encourage great design

One of the most popular features of Bootstrap is the twelve column, fully responsive grid system. By adding classes into the HTML markup, developers can create websites that react to every screen size.

Unfortunately using a predefined grid is the wrong approach to achieving a great design. The major problem is that you are designing from the outside in, shoving content into predefined boxes. The result is designs that have a rigid and mechanical feel to them, without proper proportions or harmony.

The one-size-fits-all approach also ensures that the theme you’re designing does not adapt to any constraints like image dimensions or line length. Whether you’re using a narrow sans-serif or a didone serif that needs room to breathe, the grid stays the same. The result is often bad legibility and nonharmonic typography.

A better approach


Every great theme design starts with a vision. What is the purpose behind the theme you’re designing and who do you envision using it and it what context?

This will inform you about the constraints that you have to work with. Designing an image heavy portfolio theme is a different challenge than creating an optimal experience for a magazine theme featuring long form articles.

Once you have set on a vision, you then start designing from the inside out. Get some sample content for a couple of test posts and then start designing the experience of consuming that content. You’ll see that once you focus on the content first, you can build out the remaining design elements around it and achieve a harmonic result.

On the technical side, use a starter theme that provides you with enough markup to quickly start diving into the presentational markup, without being overly opinionated about the design. Use libraries and code snippets to reduce development time. The default themes that ship with WordPress are usually a good resource for extracting code snippets.

Screen Shot 2014-08-11 at 9.30.46 AM

How to add Google fonts to WordPress themes

When enqueuing Google fonts, there are five things to consider:

  1. Is the font enqueued instead of included directly in the template files or CSS?
  2. Is the font enqueued on the correct hook?
  3. Is the font URL protocol independent?
  4. Can translators deactivate the font if their language’s character set isn’t supported?
  5. Can the font be dequeued by child themes?

In this post, we’ll go over the best practices for enqueuing Google fonts in your WordPress theme. Continue reading