Drupal Theme from Scratch Drupal Theme from Scratch icon
Theming a Drupal 7 Website



Create a Module for Drupal 7

As promised I will explain how to create a simple Drupal 7 module that will add meta tags to your pages. This module will add the following meta data to your web page source code:

  • meta description
  • fb:app_id
  • og:url
  • og:site-name
  • og:title
  • og:description
  • og:image
  • twitter:site
  • twitter:title
  • twitter:descritpion
  • twitter:card
  • twitter:image

We will also determine when and when not to add certain meta tags.

Your Module's .info File

First, we start by creating a myFunctions folder under sites > all > modules. Just like your theme, your module needs a .info file. So go ahead and create that file and save it as myFunctions.info inside the myFunctions folder. Copy the code below and save your file...

<?php
  name = "My Functions"
  description = "Additional functions for the my example website"
  core = "7.x"
  package = "My Custom Modules"

  ; files with PHP functions included in this module...
  files[] = myFunctions.module
?>

You'll notice that the code looks very similar to the .info file we created for our theme. The exceptions include the package line which creates a module group that we can use to consolidate all our custom modules, making it easier to find them all in the large modules page in the Drupal back end. The second thing to note is the comment line which starts with a ";". Finally there's the files[] line which tells Drupal what files this module uses (this is optional).

Your Module's .module File

As hinted in the code snippet above, the next file we need to create is our myFunctions.module file and it will be saved in the same folder. The following code uses Drupal's node_view function.

<?php
  function myFunctions_node_view($node, $view_mode, $langcode){
    // get page URL...
    $currentURL = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
    
    // add META DESCRIPTION TAG...
    // check to see if meta description has been filled out...
    if( !empty($node->field_meta_description) ){
      $metaDescriptionValue = $node->field_meta_description['und'][0]['value'];
    } 
    // otherwise leave it blank...
    else{
      $metaDescriptionValue = '';
    }
    
    // create FACEBOOK APP ID TAG...
    $ogFBID = array(
      '#type' => 'html_tag',
      '#tag' => 'meta',
      '#attributes' => array(
        'property' => 'fb:app_id',
        'content' => '0000000000000000',
      ),
    );
    // create OG URL TAG...
    $ogURL = array(
      '#type' => 'html_tag',
      '#tag' => 'meta',
      '#attributes' => array(
        'property' => 'og:url',
        'content' => $currentURL,
      ),
    );
    // create OG SITE NAME TAG...
    $ogSite = array(
      '#type' => 'html_tag',
      '#tag' => 'meta',
      '#attributes' => array(
        'property' => 'og:site_name',
        'content' => 'My Example Site',
      ),
    );
    // create OG TITLE TAG...
    $ogTitle = array(
      '#type' => 'html_tag',
      '#tag' => 'meta',
      '#attributes' => array(
        'property' => 'og:title',
        'content' => $node->title,
      ),
    );
    // create TWITTER SITE TAG...
    $twitterSite = array(
      '#type' => 'html_tag',
      '#tag' => 'meta',
      '#attributes' => array(
        'property' => 'twitter:site',
        'content' => '@EXAMPLESITE',
      ),
    );
    // create TWITTER TITLE TAG...
    $twitterTitle = array(
      '#type' => 'html_tag',
      '#tag' => 'meta',
      '#attributes' => array(
        'property' => 'twitter:title',
        'content' => $node->title,
      ),
    );
    /* add the following OG and TWITTER TAGS to all pages...
        - open-graph-facebook-id
        - open-graph-url
        - open-graph-site-name
        - open-graph-title
    */
    drupal_add_html_head($ogFBID, 'open-graph-facebook-id');
    drupal_add_html_head($ogURL, 'open-graph-url');
    drupal_add_html_head($ogSite, 'open-graph-site-name');
    drupal_add_html_head($ogTitle, 'open-graph-title');
    drupal_add_html_head($twitterSite, 'twitter-site');
    drupal_add_html_head($twitterTitle, 'twitter-title');
    
    $metaDescription = array(
      '#type' => 'html_tag',
      '#tag' => 'meta',
      '#attributes' => array(
        'name' => 'description',
        'content' => $metaDescriptionValue,
      ),
    );  
    $ogDescription = array(
      '#type' => 'html_tag',
      '#tag' => 'meta',
      '#attributes' => array(
        'property' => 'og:description',
        'content' => $metaDescriptionValue,
      ),
    );
    $twitterDescription = array(
      '#type' => 'html_tag',
      '#tag' => 'meta',
      '#attributes' => array(
        'property' => 'twitter:description',
        'content' => $metaDescriptionValue,
      ),
    );
    drupal_add_html_head($metaDescription, 'meta-description');
    drupal_add_html_head($ogDescription, 'open-graph-description');
    drupal_add_html_head($twitterDescription, 'twitter-description');

    /* add OG IMAGE TAG and TWITTER TAG if content type = event...
        - open-graph-image
        - twitter:card
        - twitter:image
    */   
    if($node->type == 'event'){
      if( !empty($node->field_event_image) ){
        $imageURI = $node->field_event_image['und'][0]['uri'];
        $filePath = str_replace('public://', '', $imageURI);
        $ogImage_event = array(
          '#type' => 'html_tag',
          '#tag' => 'meta',
          '#attributes' => array(
            'property' => 'og:image',
            'content' => 'https://www.examplesite.com/sites/default/files/'.$filePath,
          ),
        );
        // create Twitter META TAG...
        $twitter_card = array(
          '#type' => 'html_tag',
          '#tag' => 'meta',
          '#attributes' => array(
            'name' => 'twitter:card',
            'content' => 'summary_large_image',
          ),
        );
        // create Twitter IMAGE META TAG...
        $twitter_image = array(
          '#type' => 'html_tag',
          '#tag' => 'meta',
          '#attributes' => array(
            'name' => 'twitter:image',
            'content' => 'https://www.examplesite.com/sites/default/files/'.$filePath,
          ),
        );
      }
      else{
        $ogImage_event = array(
          '#type' => 'html_tag',
          '#tag' => 'meta',
          '#attributes' => array(
            'property' => 'og:image',
            'content' => 'https://www.examplesite.com/sites/all/themes/myTheme/images/logo.png',
          ),
        );
        // create Twitter META TAG...
        $twitter_card = array(
          '#type' => 'html_tag',
          '#tag' => 'meta',
          '#attributes' => array(
            'name' => 'twitter:card',
            'content' => 'summary',
          ),
        );
        // create Twitter IMAGE META TAG...
        $twitter_image = array(
          '#type' => 'html_tag',
          '#tag' => 'meta',
          '#attributes' => array(
            'name' => 'twitter:image',
            'content' => 'https://www.examplesite.com/sites/all/themes/myTheme/images/logo.png',
          ),
        );
      }
      // add OG IMAGE, TWITTER and TWITTER IMAGE TAGS...
      drupal_add_html_head($ogImage_event, 'open-graph-image');
      drupal_add_html_head($twitter_card, 'twitter-card');
      drupal_add_html_head($twitter_image, 'twitter-image');
    }
    
    // add generic OG and TWITTER IMAGE TAGS if content type DOES NOT = news article or event...
    if($node->type != 'event'){
      $ogImage_generic = array(
        '#type' => 'html_tag',
        '#tag' => 'meta',
        '#attributes' => array(
          'property' => 'og:image',
          'content' => 'https://www.examplesite.com/sites/all/themes/myTheme/images/logo.png',
        ),
      );
      $twitterImage_generic = array(
        '#type' => 'html_tag',
        '#tag' => 'meta',
        '#attributes' => array(
          'property' => 'twitter:image',
          'content' => 'https://www.examplesite.com/sites/all/themes/myTheme/images/logo.png',
        ),
      );
      drupal_add_html_head($ogImage_generic, 'open-graph-image');
      drupal_add_html_head($twitterImage_generic, 'twitter-image');
    }
  }
?>

The code explained...

  1. We start by getting the current URL in the browser ($currentURL) for use later.
  2. Check for the existance of a Meta Description field's value.
    • For this to work, you will need to add a text field called "Meta Description" to your content types. This will give your users the ability to edit the meta descriptions of each of their pages.
  3. If a meta description exists for the current page, the value is assigned to a variable ($metaDescriptionValue). If the user didn't remember to fill this field out, then the variable is equal to blank.
  4. Each meta tag is created the same way. Each has a #type, #tag and #attributes which contains a property and a content item.
  5. Facebook "scrapes" your website for OG tags and more and it requires the use of setting up an App ID through their site. Once you have yours, replace the "0000000000000000" with your ID number.
  6. We'll use the $currentURL from earlier for the og:url tag.
  7. For the og:site_name just replace "My Example Site" with the name of your website.
  8. The $node->title will be taken from the current page and used for the og:title tag.
  9. Replace the @EXAMPLESITE with your Twitter handle for the twitter:site tag.
  10. The $node->title will also be used for the twitter:title tag.
  11. Now that we've created all these special tags, we must add them to Drupal's page creation process using the add_html_head function.
    • Drupal has a particular way of adding things to the Head section of your HTML. You can control which tag is listed first through experimentation. This code is just how I have organized mine.
  12. Now we take the Meta Description we created ($metaDescriptionValue) and use it to create the description, og:description and twitter:description tags. And then we add them to the Head.
  13. When it comes time to create the image related OG tags, you may not have images for all your pages. So I set up an IF statement to check if the current content type ($node->type) is 'event'. If it is, then check to see if the field_event_image has been populated with an image. If it has, then use the image's URL for the og:image and twitter:image tags. And we set the twitter:card tag to 'summary_large_image'.
    • If the image does not exist, then we use a logo.png image instead for the og:image and twitter:image tags and set the twitter:card tag to 'summary'.
    Then we add the tags to the Drupal page process.
  14. For all other content types we use the logo.png image and don't bother with the twitter:card tag. Then we add the tags to the Drupal page process.

Save your file, upload your folder to your site, activate your module on the Modules page of your site and every thing should be good (you may have to flush Drupal's cache).


*If you do not see the social network icons here, it is because you have an ad-blocker running. Deactivate it for this site if you want to share this link. It is safe. There are no ads on this site.

This documentation is a work-in-progress. As I continue to learn more about the software, I will try to keep this documentation updated. I'm no expert of anything, so if anyone feels they need to correct me about something I've written or wish to add some additional tips, feel free to mention it in the comments.

"Drupal 7 Theme from Scratch" was written by TenTen71 because no one else would.