Add Open Graph Protocol meta data to your Drupal node page

Open Graph ProtocolHere's yet another handy and non-modular snippet to quickly add Open Graph meta datas to your <head> tag.

A little description about Open Graph (taken from The Open Graph protocol website):

The Open Graph protocol enables any web page to become a rich object in a social graph. For instance, this is used on Facebook to allow any web page to have the same functionality as any other object on Facebook.

Lets dive into the codes directly..

In your node.tpl.php, add the following snippet (assuming your Open Graph description is from node body):

$site_name = variable_get('site_name');
$og_title = $title . ($site_name ? ' | ' . $site_name : '');
$og_description = isset($content['body']['#object']->body[LANGUAGE_NONE][0]) ? drupal_substr(check_plain(strip_tags($content['body']['#object']->body[LANGUAGE_NONE][0]['safe_value'])), 0, 100) . '..' : '';
if ($page) {
  drupal_add_html_head(array(
    '#tag' => 'meta',
    '#attributes' => array(
      'property' => 'og:title',
      'content' => $og_title,
    ),
  ), 'node_' . $node->nid . '_og_title');
  drupal_add_html_head(array(
    '#tag' => 'meta',
    '#attributes' => array(
      'property' => 'og:description',
      'content' => $og_description,
    ),
  ), 'node_' . $node->nid . '_og_description');
}

EDIT:
Of course, you can add as many Open Graph meta data s possible, such as og:image which will produce a thumbnail image when shared in Facebook.
Refer to OGP's website for more information on the types and documentation.

EDIT 2:
Thanks to mongolito404 for suggesting to use template_preprocess_node() method.
If you want to have a cleaner and organised code, place the logic into template.php of your theme instead.

function YOUR_THEME_preprocess_node(&$vars) {
  if ($vars['page']) {
    $site_name = variable_get('site_name');
    $og_title = $vars['node']->title . ($site_name ? ' | ' . $site_name : '');
    $og_description = isset($vars['node']->body[LANGUAGE_NONE][0]) ? drupal_substr(check_plain(strip_tags($vars['node']->body[LANGUAGE_NONE][0]['safe_value'])), 0, 100) . '..' : '';
    drupal_add_html_head(array(
      '#tag' => 'meta',
      '#attributes' => array(
        'property' => 'og:title',
        'content' => $og_title,
      ),
    ), 'node_' . $vars['node']->nid . '_og_title');
    drupal_add_html_head(array(
      '#tag' => 'meta',
      '#attributes' => array(
        'property' => 'og:description',
        'content' => $og_description,
      ),
    ), 'node_' . $vars['node']->nid . '_og_description');
  }
}

14 comments for 'Add Open Graph Protocol meta data to your Drupal node page'

Nico's picture

Hi,
thx for this straightforward recipe, it's interessting because it's invisible for the author.

If you would like to give more control to the author, you could use the metatag module. The Drupal 7 version include an Open Graph sub-module.

Nico
And perhaps soon an other for Twitter Card. It's just a sandbox for now http://drupal.org/sandbox/nico059/1741784 (disclaimer, I'm the author of it). Let's see how it will evolve ...

admin's picture

Hello Nico,

You're welcome and thanks for dropping by my blog!

Yep the above snippet works seamlessly without any user intervention, if you want a better control, Metatag as suggested by you is the best way.

Your module Twitter Card, good job there! I was about to suggest to join forces with Metatag, but I found your issue here already http://drupal.org/node/1664322

=)

mongolito404's picture

Great tip, but please keep PHP snippet out of your .tpl.php. good people have build a preprocess system long ago for things like this. So put it in your in your theme's template.php or a in a module.

THEMEORMODULE_preprocess_page(&$variables) {
  if ($variables['page']) {
    $site_name = variable_get('site_name');
    $og_title = $variables['title'] . ($site_name ? ' | ' . $site_name : '');
    $og_description = isset($variables['content']['body']['#object']->body[LANGUAGE_NONE][0]) ? drupal_substr(check_plain(strip_tags($variables['content']['body']['#object']->body[LANGUAGE_NONE][0]['safe_value'])), 0, 100) . '..' : '';
    drupal_add_html_head(array(
      '#tag' => 'meta',
      '#attributes' => array(
        'property' => 'og:title',
        'content' => $og_title,
      ),
    ), 'node_' . $node->nid . '_og_title');
    drupal_add_html_head(array(
      '#tag' => 'meta',
      '#attributes' => array(
        'property' => 'og:description',
        'content' => $og_description,
      ),
    ), 'node_' . $variables['node']->nid . '_og_description');
  }
}

admin's picture

Great thank you mongolito404 for suggesting template_preprocess_node() instead. Never thought of that yesterday ... =/

Anyway, I've included your snippet above with your credit too. Thanks!

oskar calvo's picture

There is some modules to add OG.
But if you want to make it custom, you should take a look at the hook_node, and then move the variables to your template.

What you are doing make your drupal slower, it's not good to use the preprocees to get the information that should be get from hooks.

Please, teake a look at how Drupal works.

Oskar

admin's picture

What do you mean by "it's not good to use the preprocees to get the information that should be get from hooks" ?

The entire node object is already loaded by then, passed in here via $variables

And implementing template_preprocess_node is the de-facto solution for a Theme.

oskar calvo's picture

The best way is to build the new variables in the hooks, them move to the hook_theme, and the to the template.

If you make it in this way, with the preproccess function, other modules can not get the information.

If we take a look to the api doc, we find:

Use this hook when you want to add elements at the page level. For your additions to be printed, they have to be placed below a top level array key of the $page array that has the name of a region of the active theme.

By default, valid region keys are 'page_top', 'header', 'sidebar_first', 'content', 'sidebar_second' and 'page_bottom'. To get a list of all regions of the active theme, use system_region_list($theme). Note that $theme is a global variable.

If you want to alter the elements added by other modules or if your module depends on the elements of other modules, use hook_page_alter() instead which runs after this hook.

(http://api.drupal.org/api/drupal/modules%21system%21system.api.php/funct...)

You can make it as you want, but this is the correct way.

Oskar

admin's picture

Hmm you got a good point there on the other modules that cannot alter this OG value!

In that way, it should be in a module instead and might as well use Metatag to do this.

But remember, this is just a code snippet section for anyone to quickly copy+paste to get things done. You are welcomed to refer and hack it into a module of your own for custom needs.

Pacman's picture

If you want to add an image for open graph you can add this in template.php

<?php
    $image
= file_load($node->field_image['und'][0]['fid']);
   
$og_image = file_create_url(image_style_path('opengraph_facebook', $image->filename))
   
drupal_add_html_head(array(
     
'#tag' => 'meta',
     
'#attributes' => array(
       
'property' => 'og:image',
       
'content' => $og_image,
      ),
    ),
'node_' . $vars['node']->nid . '_og_image');
 
?>

opengraph_facebook is a style of image that I previously created with dimensions 200x200

customize phone cases's picture

Shopping discount personalized protective cell phone covers with cool picture on it. The largest selection of unique cellular cases &amp; skins patterns. Custom cute pattern cases for iphone 4/4s, 5/5s, Samsung galaxy note 3, note 2 7100, S3 I9300, S4 I5900 and S5.

Add new comment