Adding Facebook Opengraph META Tags to a Joomla 3 Template

There are hundreds of plugins, modules and components which add Facebook opengraph tags to your articles, but is it really necessary to add an extension for the sake of a couple of meta tags.

There was a time when Facebook ignored your standard meta tags and insisted that you add a specific opengraph tags for things like page title and description. They no longer seem to enforce this from looking at the linter with the exception of Joomla's author tag which it doesn't like because it uses meta name instead of property. In fact, after a bit of experimentation, it seems the only needed tag is the site type, everything else will be collected from the standard meta data. So lets add some tags.

I'm adding the tags to my template override for a single article. 

The standard tags available for any graph item are fb:app_id, og:type, og:url, og:title, og:image. The app id is not needed in this case, if the url is omitted then the url of the page will be used (if you have a problem with cannonical urls you can add one here), when left out the title will use the page title, when the image is left out images will be taken from the page.

So, the only tag we really need is the opengraph type tag which looks like this

<meta property="og:type" content="article"/>

You can find a full list of opengraph types here. Generally, the type will be article, I have seen people using 'blog' but this is not stated as an official type and the linter shows as article anyway.

If you click on article you will see the tags that are specifically available for the type 'article' which are as follows.

article:published_time
Type: datetime
Description: A time representing when the article was published

article:modified_time
Type: DateTime
Description: A time representing when the article was last modified

article:expiration_time
Type: DateTime
Description: A time representing when the article expired (or will expire)

article:author
Type:Array<Profile>
Description: An array of the Facebook IDs (or references to the profiles) of the authors of the article

article:section
Type: String
Description: The section of the website to which the article belongs, such as 'Lifestyle' or 'Sports'

article:tag
Type: Array<String>
Description: An array of keywords relevant to the article

Most of the info for these tags is stored in the article information, so it is just a case of retrieving it. The one exception being the author tag which needs an array of facebook id's.

You can find your Facebook id by going to http://graph.facebook.com/username so mine would be http://graph.facebook.com.went.friday you can add multiple id's separated by commas. If you have many different people authoring your site you can leave it out. So my author tag looks like this:

<meta property="og:author" content="100005501707310"/>

Other tags I have added which aren't listed are:

<meta property="og:site_name" content="Robert Went's Blog"/>
<meta property="og:locale" content="en_GB">
<meta property="fb:admins" content="100005501707310">

The site name I made up, the locale is the language of my site (you could set this using joomlas short language tag for multi-lingual sites), and the admin is my facebook id again (allows you to see statistics on the page in facebook). The other information is easy to get from within the articles layout file.

My single article layout comes from my template /html/com_content/article/default.php if you don't have this file you can copy it from components/com_content/views/article/tmpl/default.php once you look in this file is is quite obvious how to get the values we need:

JHtml::_('date', $this->item->publish_up, JText::_('DATE_FORMAT_LC4'))); //published date in correct format
JHtml::_('date', $this->item->modified, JText::_('DATE_FORMAT_LC4'))); //modified date
JHtml::_('date', $this->item->publish_down, JText::_('DATE_FORMAT_LC4'))); //expire date
$this->escape($this->item->category_title); //category name
$images->image_fulltext //featured image

We have to use the LC4 date format for Facebook to accept it which outputs like this  yyyy-mm-dd. To use the dates we also have to provide an expiration, so if this is not set I have added the year 3000 to keep the peace. The only difficultish one is the tags. You could choose to use $this->item->metakey to use the meta keywords (which is easy but who uses meta keywords), but as joomla 3.1 has a tagging feature we might as well use this so we don't have to fill in 2 different areas. To get this to work I have used a layout override to create a raw list of tags. To use it you can follow the steps here.

Now we need to get this information into the head. We add them using joomla's add tag method. At the top of my default.php file I now have this:

//add facebook tags
$doc = JFactory::getDocument();
$fbog = '<meta property="og:site_name" content="Robert Went's Blog"/>'."n";
$fbog .= '<meta property="og:title" content="'.$this->item->title.'"/>'."n";
$fbog .= '<meta property="og:url" content="http://'.($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']).'"/>'."n";
$fbog .= '<meta property="og:type" content="article"/>'."n";
$fbog .= '<meta property="og:author" content="100005501707310"/>'."n";
$fbog .= '<meta property="og:locale" content="en_GB">'."n";
if (isset($images->image_fulltext) && !empty($images->image_fulltext)) {
$fbog .= '<meta property="og:image" content="'.JURI::base().$images->image_fulltext.'" />' ."n";
}
$fbog .= '<meta property="fb:admins" content="100005501707310">'."n";
$fbog .= '<meta property="article:published_time" content="'.JHtml::_('date', $this->item->publish_up, JText::_('DATE_FORMAT_LC4')).'" />'."n";
$fbog .= '<meta property="article:modified_time" content="'.JHtml::_('date', $this->item->modified, JText::_('DATE_FORMAT_LC4')).'" />' ."n";
if ($this->item->publish_down != '0000-00-00 00:00:00') {
$fbog .= '<meta property="article:expiration_time" content="'.JHtml::_('date', $this->item->publish_down, JText::_('DATE_FORMAT_LC4')).'" />' ."n";
}else{
$fbog .= '<meta property="article:expiration_time" content="3000-01-01" />' ."n";
}
$fbog .= '<meta property="article:section" content="'.$this->escape($this->item->category_title).'" />' ."n";
if ($this->item->tags->itemTags != null) {
$this->item->rawtagLayout = new JLayoutFile('joomla.content.rawtags');
$fbog .= '<meta property="article:tag" content="'.$this->item->rawtagLayout->render($this->item->tags->itemTags).'" />' ."n";
}
$doc->addCustomTag($fbog);

If you want to use the sites active language you can read about it here.

I added an extra check to see if the featured image is set. You could extend this to grab one from the article if it isn't. You can leave this out completely and Facebook will grab an image from the page (so it depends on how cluttered you pages are).

The title and url are there just to demonstrate how they could be used.

Note: To check your opengraph tags are valid, use the Facebook linter here