Structured data for Google: how to add the ‘updated’ hentry field

This is a WordPress-specific post. I am using a modified TwentyTwelve theme and Google Webmaster Tools report missing structured data for all of my posts:

Missing "updated" field in the microformats hatom markup

Missing “updated” field in the microformats hatom markup.

In particular, it is the updated hentry field that seems to be missing. TwentyTwelve, like many themes, uses the microformats approach to communicate structured data to Google (also to others, it’s just that Google is a popular and important consumer of this data). How to correctly present date/time information to Google? A quote from their microdata docs:

To specify dates and times unambiguously, use the time element with the datetime attribute. […] The value in the datetime attribute is specified using the ISO date format.

And a quote from their microformats docs:

In general, microformats use the class attribute in HTML tags

It appears that we can combine the approaches. Might be dirty, but it works. So, what you might want to have in the HTML source of your blog post looks like this:

<time class="updated" datetime="2015-02-28T18:09:49+00:00" pubdate>
February 28, 2015

The value of the datetime attribute is in ISO 8601 format and not shown to the user. It should contain the point in time the article/blog post was last modified (updated). It is parsed by Google as the updated property, because of the class="updated" attribute. The string content of the time tag is what is displayed to your users (February 28, 2015 in this case). There, you usually want to display the point in time when the article was first published.

So, how do you get this into the HTML source code of all of your blog posts? A simple solution is to create a custom “byline” (that is what the author and date information string is often called in the context of WordPress themes), for instance with a PHP function like this:

function modbyline() {
    $datecreated = esc_html(get_the_date());
    $author = esc_html(get_the_author());
    $datemodifiedISO = esc_html(get_the_modified_time("c"));
    echo '<div class="bylinemod"><time class="entry-date updated" datetime="'.$datemodifiedISO.'" pubdate>'.$datecreated.'</time> &mdash; by '.$author.'</div>';

This creates HTML code for a custom byline, in my case rendered like so:

<div class="bylinemod">
    <time class="entry-date updated" datetime="2015-02-28T18:09:49+00:00" pubdate>
        February 28, 2015
    &mdash; by Jan-Philip Gehrcke

The user-visible date is the article publication date, and the machine-readable datetime attribute encodes the modification time of the article. Note that WordPress’ get_the_modified_time() by default returns a date string with a human-readable default format. In order to make it machine-readable by ISO 8601 standard, you need to provide it the "c" format specifier argument (I have done this in the function above).

You want to define this custom byline function in your (child) theme’s functions.php. It should be called from within content.php.

After inclusion use Google’s structured data testing tool for validation of the approach. It should show updated entry, containing the correct date.