Introducing REST APIs

Welcome back to our tutorial on building themes with JavaScript. In part one, we considered the JavaScript web landscape and looked at where we are today. I suggested that while JavaScript lets us render content in new and interesting ways, there are challenges when it comes to fetching the content in the first place.

Watch the video presentation or read the written transcript below.

Screencast

Demo Materials

You’ll find accompanying material for this screencast available in a public GitHub repo — each screencast has a corresponding folder with very simple theme that can be activated.

Time for a REST

With traditional WordPress themes, we’ve been able to use all manner of loops and custom queries to get data. In shifting our approach to be less PHP-centric, where will our data come from?

The missing piece of our puzzle is a REST API, essentially an HTTP interface for getting data from a source. The REST part stands for REpresentational State Transfer. Think of it as a way of accessing WordPress queries directly through a URL. We can type a URL into our browser and include parameters just like we would with a custom loop, and in the browser we can see pure data from our website.

A REST API also allows you to post data, so the WordPress REST API allows you to add and update content directly without using the admin interface. Certain types of requests do need authentication, the REST API only publicly exposes content which is already revealed by WordPress through other avenues, like RSS feeds.

This all means that you don’t have to worry about connecting to a database, you just use a series of URLs to access different types of content on your site — these are known as endpoints.

The WordPress REST API is due to be fully incorporated in WordPress 4.5, due in the spring of next year. In fact, the infrastructure of the WordPress REST API will be included with WordPress 4.4 and has already been merged into trunk.

Exploring the WordPress REST API

Next, let’s look at some of the basic things we can do with the WordPress REST API.

I have a WordPress environment set up locally where I have installed WP API. Ahead of its inclusion in core, WP API is available as a plugin on the WordPress plugin repository. With the plugin activated, I can navigate to the URL /wp-json/. At this URL I can see an overview of everything that the REST API makes available to me.

Screen Shot 2015-11-25 at 17.39.08

As the URL suggests, WP API uses JSON formatted data. This is not compulsory for REST APIs, but most REST APIs will use either JSON or XML formatted data. More recently JSON is the preferred format as it’s less verbose and generally easier to work with. I’m also using a Chrome extension called JSON View, which adds sane line breaks and some colours to make it easier to read the JSON. Without JSON View, the JSON data is quite hard for a human to read!

The REST API adds namespaces to its endpoints. This is to ensure that extensions and future versions of the API don’t break functionality for sites and software that use it. The primary namespace at the moment is wp/v2. This means that we can build our website against version 2 of the REST API. If, in the future, it’s decided that the REST API should be structured differently, this restructure would happen under the namespace of wp/v3. Therefore the REST API could completely change, but what we built for v2 would be safe with the inherent backwards compatibility of the v2 namespace.

So, if we navigate to /wp-json/wp/v2/ we can see all of the information about this namespace. As newcomers, we don’t have to worry about this at the moment, but it’s worth understanding the path we take to what we’re really trying to get from the REST API.

If we add posts/ to the end of the above URL, we finally start seeing the data from our website. By default, posts/ will show us the same content that a generic loop on our homepage would. On a clean install of WordPress, this is usually the 10 most recent posts.

Screen Shot 2015-11-25 at 17.39.35

We can further narrow down our request to the REST API by adding a post’s ID to the URL. So in this instance, /wp-json/wp/v2/posts/1241/ will show us just the one post with ID 1241.

The REST API provides typical things that we might want in relation to a post. We can see the date, modified date, permalink, title, content, excerpt, format, whether or not it’s sticky, and more.

Now let’s consider an example where we use the REST API to render content on a page using JavaScript.

I’ve set up a basic HTML document set up in my text editor, including a div with the id "page", an anchor link with text “Hello world,” and an empty h1 and div element. The div has an id of "content".

Beneath that, we have some inline JavaScript inside a script tag. To begin, we use JavaScript’s native XMLHttpRequest API to fetch our data. This is what’s behind jQuery’s Ajax functions, you may remember this from part 1 when I spoke about the website YouMightNotNeedjQuery.com.

What this does is fetch the URL from the REST API that we were just looking at. If it’s successful, it will parse the JSON response so that we can access the different elements as a JavaScript object. We then use the querySelector and innerHTML methods to change the data in the HTML on this page. At the moment we aren’t dealing with errors, we would want to deal with these if we were doing this in production.

Let’s see how this works. If I activate the session 2 theme on my test site, we can see what this does. There we go, the data from the REST API is being rendered in my theme demo.

One last thing before we end this tutorial. We still have that link that I added at the top — let’s look at how this is connected.

Well, if we go back to the index of our little theme and scroll down, you can see we also have a function, changePost. This does exactly the same thing as the other bit of JavaScript, but it gets a different post (with ID 1). Beneath this, you can see that we add an event listener to the link. The link listens for a click, if it gets clicked it fires the function. Let’s see what happens.

There we have it.

You can now see how a very basic WordPress REST API-based theme can work. In the next screencast we will consider more advanced approaches to theming and the challenges we face when taking this approach.

The Series

  1. JavaScript, jQuery and the web landscape today
  2. Introducing REST APIs
  3. Challenges in JavaScript-Based Theming
  4. Bringing React into our theme
  5. Et voila, a JavaScript WordPress theme that uses the WordPress REST API

The ThemeShaper JavaScript Theme Tutorial

Dive into the brave new world of JavaScript WordPress theming, looking at best practices and pitfalls along the way.

Introduction

WordPress theming hasn’t changed very much over the past few years. It’s certainly become more refined, and projects such as Underscores (_s) have helped promote best practices and robust standards. That said, we can still go as far back as Kubrick and find plenty of common ground with the most recent WordPress themes.

This isn’t a bad thing, and it’s probably one of the reasons WordPress is so popular and so many people have been able to get involved in theming. But the web has changed substantially since WordPress welcomed its first default theme in 2006. More than half the web’s users now access it from mobile devices. We have HTML5, and with it a whole host of browser APIs that didn’t exist in 2006. These advances have helped a whole new ecosystem of JavaScript-based web apps blossom.

Some aspects of this ecosystem have found their way into WordPress themes. Most of us have probably seen our fair share of jQuery-enabled carousels. We have JavaScript-enhanced tiled galleries and lightboxes available through plugins like Jetpack. Yet very few of us would consider building a theme entirely in JavaScript. The thought may even send shivers down many of our spines.

Building a WordPress theme with JavaScript might be considered lunacy by some, who may wonder why you’d want to attempt such a thing. Others may have questions about SEO, performance, accessibility, plugin compatibility, among a myriad of issues. There are definitely challenges to building a theme with JavaScript, and before reading any further you should know that this is still an experimental area of WordPress theme development.

But, and this is a big “but,” a JavaScript-based approach to theme-building opens up a wonderful world of new possibilities to the curious developer, including:

  • Storing and pre-fetching content using the browser’s Web Storage API to allow server-less, seamless transitions — using the browser’s History API — between posts and pages.
  • Animations within themes, for more natural and intuitive interactions.
  • The ability to create entirely offline experiences using all new Service Workers.

Along with these exciting improvements, the WordPress REST API is being integrated into Core. The REST API makes it much easier for us to build themes with JavaScript. There is no better time to start getting familiar with how the WordPress ecosystem is changing.

The Series

In this five-part tutorial, we’ll expose you to the brave new world that WordPress theme development might inhabit in the coming years. While the best practices for building a theme in this way are still to be established, we’ll do our very best to guide you into the secret garden of the future.

Stay tuned for:

  1. JavaScript, jQuery and the web landscape today
  2. Introducing REST APIs
  3. Challenges in JavaScript-Based Theming
  4. Bringing React into our theme
  5. Et voila, a JavaScript WordPress theme that uses the WordPress REST API

JavaScript, jQuery and the Web Landscape Today

This is the first in our five-part series on building WordPress themes with JavaScript. Let’s kick things off with an overview of today’s web landscape and how JavaScript fits in. The vast majority of WordPress themes today use jQuery for at least something, so I’ll look at how we’re building themes today, and how we can think about using JavaScript techniques that may be less familiar.

Check out the video presentation or the written transcript below.

Screencast

A Brief History of JavaScript

What is JavaScript? In Douglas Crockford’s JavaScript: The Good Parts he describes JavaScript as the language of the browser. It enables developers to manipulate the web browser, and therefore affect users’ interactions with the browser. This is at the core of why we should even be thinking about JavaScript in the context of theming.

I’m not just talking about the DOM (Document Object Model). Of course, without JavaScript we can control what the user sees in the browser. But with JavaScript, we can interact with things beyond the DOM. We can edit the browser’s history, we can store data in the browser’s memory, and now we can even create push notifications. This takes us even further than the browser and into the user’s device.

For a long time, JavaScript also allowed us to do things asynchronously, loading things in the background while the user is doing something else. Google, via Gmail, have been doing this since 2004. At that point, working with JavaScript was prohibitively difficult, and unless you had a lot of developers and money, you didn’t generally use it in the way Google did. That said, developers did start making basic use of the Ajax techniques that Google largely pioneered with Gmail. Ajax stands for Asynchronous JavaScript and XML.

Getting Our Hands Dirty

Let’s look at some simple things we can do with JavaScript in Chrome’s developer console, using the BBC website as an example. (All modern browsers have an equivalent way of doing this.) I’m not going to use jQuery, just so we can get more comfortable with the idea of pure JavaScript.

First, we want to select something in the DOM. The two most common methods for doing this are getElementById and querySelector. They’re similar, except with querySelector we can select elements by their class. As its name suggests getElementById only allows us to select elements by their ID.

With something selected, we could now change pretty much anything about it. This is basically what jQuery does behind the scenes.

jQuery etc.

I’ve mentioned jQuery a few times. Years ago, many felt JavaScript was arcane and hard to understand. There were a lot of browser inconsistencies and compatibility issues. The jQuery project, which kicked off in 2006, tried to abstract the difficult problems with JavaScript, and allow people to more easily make use of it. At its essence, jQuery is a library of abbreviations. A great introduction to jQuery is the website YouMightNotNeedjQuery.com.

When this site first went live it was the butt of a lot of jokes, but it’s actually quite a useful resource. On the one hand we can see how jQuery really does shorten how much code we need to write, but sometimes the jQuery version is no shorter than pure JavaScript. Occasionally, the jQuery way is even slightly longer, such as with outerHTML.

I’ve used jQuery a lot in my time as a developer and while it can be useful, I do believe that jQuery can restrict those using it to what it is able to do. I also think that because of jQuery, a lot of developers remain mostly unfamiliar with JavaScript itself.

It’s also worth noting that there are/were some other players in the same field as jQuery, for example MooTools and YUI.

A Whole New Node

In 2009, JavaScript saw the start of a bit of a renaissance, as Node.js landed, which allowed you to run a server with JavaScript. The JavaScript renaissance really hit its stride in 2011 with the arrival of npm, the Node Package Manager. This was huge because it made it trivial to create and distribute JavaScript modules. In a way, npm is like a JavaScript version of the WordPress plugin repository. Since Node’s arrival, lots of new JavaScript libraries and frameworks have come onto the scene including Backbone, Ember, Angular, and React.

These new libraries and frameworks have made it easier for developers to create quite impressive app-like websites with JavaScript. At the same time, many of the browser inconsistencies and compatibility issues with JavaScript have been ironed out. We are now in a position with JavaScript where we can take pretty much complete control of the user’s experience on our websites. The one missing piece of the puzzle in the context of WordPress is data. Yes, we can manipulate the DOM and move things around, but how do we get the data from WordPress? That’s where the REST API comes in, and that’s what I’ll be focusing on in the second part of this tutorial.

The Series

  1. JavaScript, jQuery and the web landscape today
  2. Introducing REST APIs
  3. Challenges in JavaScript-Based Theming
  4. Bringing React into our theme
  5. Et voila, a JavaScript WordPress theme that uses the WordPress REST API

Theming with the REST API – Meet Picard

If there’s one thing that has been making waves in the WordPress ecosystem this year, it is the new REST API. Officially known as WP-API, and currently available as a plugin, it is due to be rolled into core at some point this year.

A REST API?

A REST API may not initially seem like a useful feature for theme developers. It is clearly very useful for those looking to use WordPress as an application platform, but how the REST API can be used within a theme is perhaps more opaque.

The Theme Division at Automattic have had an eye on the potential uses of a REST API powering a theme for at least a couple of years now, and in recent months some concepts have started to take shape.

The Future is JavaScript

There are many potential benefits to building themes that rely more than ever before on JavaScript and the REST API, including but not limited to:

  • Design: We can have smooth transitions between the different types of content on our websites.
  • Speed: We can store content from the REST API in localStorage (effectively the browser’s memory). This means that on the initial site load we can store any post that is retrieved. Imagine a user clicking a ‘read more’ link and the full post being displayed without the need of a further server request.
  • Offline: By handling interactions with JavaScript, as developers we gain control of what happens if the user goes offline while browsing our site. We can let them know that the server doesn’t appear to be reachable and we can present content that we know is stored in their browser in a graceful way.

Picard Screenshot

Picard

In February of this year, the team worked together on a prototype REST API theme that has become known as Picard (a geeky nod to “the next generation” of themes). To create Picard, we used React, a JavaScript library for building user interfaces. Coupled with vanilla JavaScript and a number of other libraries sourced through npm, we were quickly able to produce an engaging, working prototype.

Recently, I have been talking about building themes with the REST API and our approach to building Picard at a number of WordCamps so far this year, culminating in a workshop at the inaugural LoopConf.

Today, Picard is now publicly available on GitHub.

Tango

We intend to continue developing Picard and working on some of the harder problems that we have not yet solved. We aren’t stopping at Picard either. Our experiments have led us in various directions. My colleague Kirk Wight has created another experimental theme called Tango. Tango is an extension of the concepts we are exploring with Picard, blended with the bulletproof Underscores starter theme.

Make It So

The future of WordPress theming may dramatically shift with the official adoption of the REST API but you don’t have to wait for the future to take advantage of it now. Clone Picard and Tango. Experiment and see what you can do. These are exciting times for themes!

Further Reading and Resources


 

Photo credit: JD Hancock/flickr

Building a Strong Foundation with Keyboard Accessibility

Learn how keyboard accessibility can serve as your foundation for an accessibility-ready theme, helping you create a solid base.

When you build a house, you start with the foundation. It becomes the base upon which you form everything else around. Without it, your house could crumble because of improper construction. Web accessibility shares some of the same principles. You need a solid foundation to have an accessible website and WordPress theme.

Keyboard accessibility can serve as your foundation for an accessibility-ready theme, helping you create a base that you can build on with confidence. Once you have it in place, accessibility becomes easier as you go.

Keyboard Accessibility Principles

But where do you start? You can tackle any of the four principles below one at a time. Pick one, practice implementing it in your next theme, and you’ll see the benefits. Bringing these to your project matters more than mastering them in any specific order.

Use the Keyboard

Know how to navigate with a keyboard alone. WebAIM, a non-profit organization focused on web accessibility, has an excellent article on keyboard accessibility. It includes how to use a page with the keyboard alone. From the article:

With modern web accessibility, there are many ways in which keyboard accessibility can become difficult or impossible. Fortunately, keyboard testing is easy – simply put the mouse away and test the page using only a keyboard. The tab and shift + tab keys can be used to navigate through links and form controls, and Enter can be used to activate links, buttons, or other interactive elements.

Who uses the keyboard every day on the Web? People who are blind use it almost exclusively. People with low vision may also use it if a page can be enlarged and the contrast is high enough. Those with motor disabilities often can’t use a mouse. Alternative devices also come into play too, like those that allow users to “puff and sip,” and work with airflow from the mouth. These devices interact with the computer similar to a keyboard, so they benefit from proper keyboard accessibility.

Watch your Source Order

Keep your source order in mind. Source order means how your HTML is ordered and how it flows on the page. As you create your theme, make sure that it’s logical. Turning off CSS provides a good, simple way to test this. Once everything on the page becomes linearized, does it still make sense?

Links and Buttons are Links and Buttons

Use semantic HTML and controls that have accessibility already built in. This means that links Home and buttons Main Menu are your best choice. Only three elements in HTML can be focused on by default: links, buttons and form fields. If you use a

or to create an element that’s clickable via JavaScript, a keyboard user will not be able to reach that element. Sure, you can use JavaScript to make it focusable, but why would you if HTML already does the work for you? If you don’t like the default styles of a normal , then you can style it however you’d like with CSS.

Don’t Lose Your :focus

Design and pay attention to the :focus states for your theme. Users with disabilities have an array of needs that don’t always start with a screen reader. Many users access the web using a keyboard alone, or other devices that rely on keyboard access to navigate the web. Having visual :focus styles on elements like links, buttons and form fields means they can see where they are as they navigate. For example, Underscores comes with this bit of CSS on links in the Reset section:

a:focus {
	outline: thin dotted;
}

a:hover,
a:active {
	outline: 0;
}

Having a thin, dotted outline on :focus is considered the default focus style in most browsers. It’s a good place to start, but if you’d like something different, you can design it. However, do not completely remove focus styles by setting outline: 0. That leaves your theme unusable by people who depend on the keyboard. Focus states can often mimic hover states, but they do not have to be identical. The important point here is that they do not rely on color alone. Many users have varying degrees of color blindness and/or low vision. Relying on color alone can become problematic. Using an outline, border or some other kind of shape helps your focus styles shine.

Potential Problems and Enhancements

Keyboard accessibility can become more complex in a few places. Patterns like dropdown menus, menu toggles, tabs, and modals require extra care and thought, but the same principles apply. Knowledge of the tab index attribute and ARIA roles and properties come in handy here. These advanced techniques are beyond the scope of this article, but some useful posts and tutorials have more information:

Further Reading and Resources

Let me know if you have any questions in the comments. Happy theming with accessibility in mind!

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!

Working with the Eventbrite API Plugin

Eventbrite and WordPress are the perfect fit, but until now, integrating the two has not been for the faint of heart. In early 2014, Eventbrite announced its new upcoming REST API, and this became the perfect opportunity to give theme developers an easy-to-use set of tools for working with Eventbrite events: the Eventbrite API plugin.

The plugin gives theme developers three ways to interact with the Eventbrite API:

  • Theme support
  • The Eventbrite_Query class
  • Helper functions

Theme Support

While the Eventbrite API plugin can display events in any theme, events look their best if the theme declares support and provides tailored templates. This simple process guarantees that events fit perfectly with the theme design, and adding support should take no more than ten minutes.

  1. Add a support declaration, hooked to after_setup_theme. There are no arguments, and usually this can be added to a theme’s existing setup function.
    function themeslug_setup() {
    
    	...
    
    	/**
    	 * Add theme support for the Eventbrite API plugin.
    	 * See: https://wordpress.org/plugins/eventbrite-api/
    	 */
    	add_theme_support( 'eventbrite' );
    }
    add_action( 'after_setup_theme', 'themeslug_setup' );
    
  2. Create an eventbrite folder in your theme, and copy over the plugin’s main template files (tmpl/eventbrite-index.php and tmpl/eventbrite-single.php).
  3. Compare the markup in eventbrite-index.php to your own index.php and adjust as necessary. Also, verify that your markup for archive titles matches the Eventbrite template’s page title. The Eventbrite templates don’t use template parts for the post markup, so you may need to compare with content.php or the like. Of course, there’s no reason you couldn’t add a content-eventbrite.php to your theme, if you prefer.
  4. Repeat step 3 with eventbrite-single.php and your own single template.

That’s it! If support is declared, the plugin will use those templates if they exist, or fall back to the plugin’s templates. To see some custom templates in action, check out any of the Twenty* default themes; their templates are included in the plugin.

Eventbrite integration with Twenty Fifteen.
Eventbrite integration with Twenty Fifteen.

The Eventbrite_Query Class

It was important to us that working with the Eventbrite API plugin should be a simple and familiar process for theme developers, with a low barrier to entry. With that in mind, we developed the Eventbrite_Query class, so fetching and displaying events is as simple as making a secondary loop (in fact, the class extends WP_Query). This allows for easy creation of special-purpose loops, widgets, creative page templates – any combination of events you want to display in a theme.

<?php
	// Get the next three unpublicized events for the Apollo Planetarium.
	$events = new Eventbrite_Query( apply_filters( 'eventbrite_query_args', array(
		'display_private' => true,
		'limit' => 3,
		'venue_id' => 6955925,
	) ) );

	if ( $events->have_posts() ) :
		while ( $events->have_posts() ) : $events->the_post(); ?>

There are a few things to keep in mind while working with Eventbrite_Query loops.

  • You can continue to use familiar template tags in event loops, such as the_post_thumbnail(), the_title(), the_content(), etc. They’ve simply been filtered to provide content from the current event.
  • For technical reasons, a few template tags need their Eventbrite equivalent, such as eventbrite_is_single() and eventbrite_edit_post_link().
  • Being a secondary loop, don’t forget to add wp_reset_postdata() at the end.
  • All of the plugin’s template tags are pluggable, and filters exist at various points for further customization.

Helper Functions

If you’re happy processing your own results, and just want an easy-to-use set of tools to handle the API requests, the included helper functions are for you. Each supported API endpoint has its own helper function, and these functions in turn use the Eventbrite_Manager class for the heavy lifting. Not only does this class make the actual API requests, but also handles validation and transients, so you can concentrate on results rather than mechanics.


The Eventbrite API plugin is developed on GitHub, and issues or questions can be posted there or in the forums. Additional info and documentation can be found here.

Along with the Eventbrite Services plugin, it’s never been easier or more fun to display events in your WordPress website. Let us know what you’re doing with Eventbrite, and tell us if there’s anything the Eventbrite API plugin can do to make your Eventbrite integrations easier for you!

The Eventbrite API plugin requires the Keyring plugin for managing OAuth2 authorization to Eventbrite. If you get stuck, check out our detailed instructions for getting connected to Eventbrite.

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?