Adding Microdata to Joomla Articles

Google has been using microdata for quite a while now and adding it to your website can help with clickthrough rates from search engine results.

The most obvious is Google's own authorship markup (not strictly microdata per se) where linking to your Google+ profile adds your profile image to pages in search results, but there are many other tags which can be added to display extra information next to your page title and description.

In this article I am going to look at adding microdata for article publishing times, images and authors to Joomla 3.

Note: If you only want to add Google authorship links then read the post about how to add Google authorship to Joomla articles

I'm not sure how useful adding microdata to an image is but it is an easy example to start with as the property will always be the same. So, overriding the standard article view (templates/mytemplate/html/com_content/article/default.php) find the code which outputs the featured image.

<div class="pull-<?php echo htmlspecialchars($imgfloat); ?> item-image"> <img
<?php if ($images->image_fulltext_caption):
echo 'class="caption"'.' title="' .htmlspecialchars($images->image_fulltext_caption) . '"';
endif; ?>
src="<?php echo htmlspecialchars($images->image_fulltext); ?>" alt="<?php echo htmlspecialchars($images->image_fulltext_alt); ?>"/> </div>

All we need to do is add an itemscope to the parent div and an item property to the image it's self. You can read more about the subject here  http://schema.org/docs/gs.html

<div class="pull-<?php echo htmlspecialchars($imgfloat); ?> item-image" itemscope> <img
<?php if ($images->image_fulltext_caption):
echo 'class="caption"'.' title="' .htmlspecialchars($images->image_fulltext_caption) . '"';
endif; ?>
src="<?php echo htmlspecialchars($images->image_fulltext); ?>" itemprop="image" alt="<?php echo htmlspecialchars($images->image_fulltext_alt); ?>"/> </div>

And that is it. You can test that Google is recieving the correct data using the rich snippets testing tool  http://www.google.com/webmasters/tools/richsnippets

Next, lets do the dates. All the information we need is stored in the database so it is just a case of outputting it in the correct format. The standard date bloc looks like this:

<?php if ($params->get('show_publish_date')) : ?>
<dd class="published">
<span class="icon-calendar"></span>
<?php echo JText::sprintf('COM_CONTENT_PUBLISHED_DATE_ON', JHtml::_('date', $this->item->publish_up, JText::_('DATE_FORMAT_LC3'))); ?>
</dd>
<?php endif; ?>
<?php if ($params->get('show_create_date')) : ?>
<dd class="create">
<span class="icon-calendar"></span>
<?php echo JText::sprintf('COM_CONTENT_CREATED_DATE_ON', JHtml::_('date', $this->item->modified, JText::_('DATE_FORMAT_LC3'))); ?>
</dd>
<?php endif; ?>
<?php if ($params->get('show_modify_date')) : ?>
<dd class="modified">
<span class="icon-calendar"></span>
<?php echo JText::sprintf('COM_CONTENT_LAST_UPDATED', JHtml::_('date', $this->item->modified, JText::_('DATE_FORMAT_LC3'))); ?>
</dd>
<?php endif; ?>

The date needs to be in the format yyy-mm-dd which we can get by using Joomla's DATE_FORMAT_LC4. Again, we need to add an itemscope to each of the dates which I'm going to add to the dd tags. Next I'm wrapping the spans with a html5 <time> tag which uses the correct itemprop for articles  http://schema.org/Article

<?php if ($params->get('show_publish_date')) : ?>
<dd itemscope class="published">
<span class="icon-calendar"></span>
<time itemprop="datePublished" datetime="<?php echo JHtml::_('date', $this->item->publish_up, JText::_('DATE_FORMAT_LC4')); ?>">
<?php echo JText::sprintf('COM_CONTENT_PUBLISHED_DATE_ON', JHtml::_('date', $this->item->publish_up, JText::_('DATE_FORMAT_LC3'))); ?>
</time>
</dd>
<?php endif; ?>
<?php if ($params->get('show_create_date')) : ?>
<dd itemscope class="create">
<span class="icon-calendar"></span>
<time itemprop="dateModified" datetime="<?php echo JHtml::_('date', $this->item->modified, JText::_('DATE_FORMAT_LC4')); ?>">
<?php echo JText::sprintf('COM_CONTENT_CREATED_DATE_ON', JHtml::_('date', $this->item->modified, JText::_('DATE_FORMAT_LC3'))); ?>
</time>
</dd>
<?php endif; ?>
<?php if ($params->get('show_modify_date')) : ?>
<dd itemscope class="modified">
<span class="icon-calendar"></span>
<time itemprop="dateCreated" datetime="<?php echo JHtml::_('date', $this->item->created, JText::_('DATE_FORMAT_LC4')); ?>">
<?php echo JText::sprintf('COM_CONTENT_LAST_UPDATED', JHtml::_('date', $this->item->modified, JText::_('DATE_FORMAT_LC3'))); ?>
</time>
</dd>
<?php endif; ?>

That takes care of the publishing times. The authorship is a bit more complicated as by default there is no field for a user to add a link to their Google+ profile. It the case of this blog I am the only writer so I can hardcode the author link to my profile.

<span class="createdby" itemscope itemtype="http://schema.org/Person">
Written by <a itemprop="url" href="https://plus.google.com/114266924568110882143" target="_blank" rel="author"><span itemprop="name" ><?php echo $author; ?></a>
</span>

If you have multiple users then you need to go to the contacts component and create a contact for each user and add the Google+ link to the website field (this in its self may be enough for it to work if articles are linked to the profile page). We can then change the link to use this field instead of the standard one and add our microdata.

<?php if ($params->get('show_author') && !empty($this->item->author )) : ?>
<dd class="createdby" itemscope itemtype="http://schema.org/Person">
<?php $author = $this->item->created_by_alias ? $this->item->created_by_alias : $this->item->author;
$author = '<span itemprop="name">'.$author.'</span>'; ?>
<?php if (!empty($this->item->contactid) && $params->get('link_author') == true) : ?>
<?php
$needle = 'index.php?option=com_contact&view=contact&id=' . $this->item->contactid;
$menu = JFactory::getApplication()->getMenu();
$item = $menu->getItems('link', $needle, true);
$cntlink = !empty($item) ? $needle . '&Itemid=' . $item->id : $needle;
$db = JFactory::getDbo();
$query = 'SELECT `webpage` FROM `#__contact_details` WHERE `id` = '. (int) $this->item->contactid;
$db->setQuery($query);
$page = $db->loadResult().'?rel=author';
?>
<?php echo JText::sprintf('COM_CONTENT_WRITTEN_BY', JHtml::_('link', JRoute::_($page), $author, array('target' => '_blank', 'itemprop' => 'url'))); ?>
<?php else: ?>
<?php echo JText::sprintf('COM_CONTENT_WRITTEN_BY', $author); ?>
<?php endif; ?>
</dd>
<?php endif; ?>

So there we have it, microdata added to our Joomla articles. You can add any of the properties mentioned in the schema page  http://schema.org/Article 

Tip: Test your snippets using the Google rich snippets tool http://www.google.com/webmasters/tools/richsnippets