Standardising WordPress theme hooks

I’ve been working on integrating our SEO plugins more deeply with Genesis the last few weeks and something dawned on me. Ever since I wrote my post on Genesis 2.0, I’ve been thinking: Genesis started a small revolution, but we should open that up. More theme developers should start doing a Schema.org API and if they do, we should make sure they’re interoperable.

In short: Genesis 2.0 added a Schema.org API, with hooks like:

  • genesis_attr_entry
  • genesis_attr_entry-title
  • genesis_attr_entry-content

These hooks are very consistently named, which is very important. There’s one “issue” though: they’re namespaced. They all start with “genesis_”, which is a good practice by the Genesis community and one most theme authors use. But let’s think about this from a plugin authors perspective: if I add support for Genesis Schema.org API and say WooThemes decides to adopt it as well but prefixes it with “woo_”. And then 10 other theme vendors do the same thing. Instead of having one line of code that filters a specific hook’s output, I have 10 add_filter lines to add, and I need to do that for every change.

The same is true with some other hooks that loads of us plugin developers need but WordPress core refuses to add. I’ve had lengthy discussions about the need for a body_open hook in core, but the core team has all sorts of reasons not to want that. I see why, but that doesn’t stop us, as the WordPress community, with coming up with our own standards for hooks and standardizing them in a proper fashion.

WordPress theme hook standardisation board

I think we should be able to get the big theme guys together and come up with a proper standard for these things and it wouldn’t even need much work. Because genesis naming is so elegant, everyone could copy their schema.org API and prefix it with their own standard prefix. The only thing we have to decide on together is a constant we define for the theme prefix.

I’d say WP_THEME_NAMESPACE would be good. What that would allow is for Genesis to define that constant as “genesis”, and for me as a plugin author to hook into that:

add_filter( WP_THEME_NAMESPACE . '_attr_entry', 'yoast_filter_function' );

This would then work with every theme that has support for that API and has defined the theme’s namespace. For other hooks it might be a bit more work, what I’d call “body_open” is in Genesis as “genesis_before”, which is semantically a bit weird in my opinion, but we should discuss.

I’d love to come up with a proper standard for these things. Which is why I’m calling for the formation of a WordPress theme hook standardisation ”board”. I’d love to standardise hooks that all big themes have in such a way that plugins can start to rely on them. We shouldn’t “rely” on the core team to do this, in my opinion. I’d love to get StudioPress, WooThemes and all of the other theme people on board and do this together. If you represent a theme company and would like to join, jump in in the comments and I’ll contact those of you who “register” their support to come up with a proper way of discussing this.

Update: of course 10 seconds after publication @nacin tells me something like this already exists in part: the Theme Hook Alliance. We should probably all work together :)

 

This post first appeared on Yoast. Whoopity Doo!

Schema.org & Genesis 2.0

About a week ago, we “migrated” Yoast.com to Genesis 2.0, in the process we switched to their new HTML5 / Schema.org code and we slightly updated our design, making the header shorter and making improvements to our responsive design. This was a bit of work, but not even half as much as that sounds like and that is due entirely to the fact that Genesis 2.0, and especially it’s schema.org functionality, rocks. Let me elaborate.

Why implement Schema.org markup?

Let me start with explaining why you should be bothered with schema.org if you weren’t convinced yet. Not just Google uses schema.org, all 4 major search engines, Google, Yahoo!, Bing and Yandex use it for several different purposes. Yandex recently started doing something that’s way cooler than Google’s rich snippets, you should check that out. But it’s not just them. Recently, Pinterest joined the party by announcing support for Product, Recipe and Movie schema’s through their Rich Pins effort.

So, in my opinion, schema.org markup is a must for everyone serious about their websites optimization.

General service warning: what follows is rather geeky. If you’re not a developer but you do use Genesis or are considering it, feel free to forward this to your developer.

Schema.org enhancements

This site runs a custom Genesis child theme. Most of the CSS and Genesis work for that was done by the awesome Bill Erickson, but I took quite some time after he’d finished to add in all sorts of schema.org goodness to pages. I want my site to be a living example of what is possible from a rich snippets perspective in the SERPs and I use it to experiment with things all the time.

We have a few different post types here on Yoast, which each have their own Schema.org counterpart. Take, for instance, my speaking page. I have a post type for speaking events, and the speaking page is actually the post type archive for that post type. If you test that page with the Structured Data Testing Tool Google provides, you’ll see it’s marked up with cool Event schema’s, which will show up in the search results too:

Speaking Page - Showing event schema markup

There are various ways you could reach this with Genesis, I do it by creating a file, archive-speaking_event.php, where “speaking_event” is the name of the post type. Basically, to get this file to display the post type archive, all it needs to have is the following code:

genesis();

But in our case, we want to do a bit more. We need to mark up each individual post as an Event type and link them to the appropriate URLs for the individual events. Also, there’s all sorts of output that we’ll need to gather, like dates, location names, addresses and countries. Let’s start with the easy bits:

Changing the Schema type of an entries output

First of all, add this file to your child theme by including it from your functions.php. If you simply add it to the same directory it’s as simple as adding this to the end of that file:

require('genesis-schema-helper-functions.php');

That file contains helper functions we’ll need to do all the work. Now remember, this used to take all sorts of extra divs to do well or you were required to rewire the base framework. With Genesis 2.0 though, it’s as simple as adding this before the genesis() call:

add_filter( 'genesis_attr_entry', 'yoast_schema_event', 20 );
add_filter( 'genesis_attr_entry-title', 'yoast_itemprop_name', 20 );
add_filter( 'genesis_attr_entry-content', 'yoast_itemprop_description', 20 );
add_filter( 'genesis_post_title_output', 'yoast_title_link_schema', 20 );
add_filter( 'genesis_attr_content', 'yoast_schema_empty', 20 );

This does the following:

  • turn the schema type of each individual entry on the page into an event;
  • replace the normal “headline” itemprop for the entry title with “name”, as required by this specific schema;
  • change the itemprop of the entry content to “description”, instead of “text”, which is the default for a blog post;
  • make sure the link in the headline has the itemprop=”url” needed;
  • remove the overall schema.org type of the page as that would confuse the search engine.

The basic work is now done, of course we need all the meta data, and we’ll need to retrieve that in the conventional way. The code I used for that can be found in the gist I created for this file.

This bit of work replaced hundreds of lines of ugly code with easily readable and easily applicable code which as a bonus actually has less of a need for extra divs etc in the output. I absolutely love it. If you want to see more examples of pages on this site with cool Schema markup, check these:

  • my Genesis review, which itself has beautiful review markup, as you can see here.
  • my plugin pages, for instance my WordPress SEO plugin page, which has product + review markup, see here.
  • this, or any other post, which has the default Genesis 2.0 blogposting markup.

Genesis 2.0 is still in beta, and I’ve been discussing several possible changes with Nathan Rice, Genesis’ Lead Developer, that would make some of this work even easier. This is where the future lies though: more and better markup for pages with a theme that allows you to easily add the metadata you need. I’m considering adding some Genesis specific functionality to WordPress SEO to make all this even easier, I’d love to know your thoughts and what you’d like to do with all this.

Schema.org & Genesis 2.0 is a post by on Yoast - The Art & Science of Website Optimization. A good WordPress blog needs good hosting, you don't want your blog to be slow, or, even worse, down, do you? Check out my thoughts on WordPress hosting!