Customizing and Theming Drupal Node Info - The $submitted variable

In most of the Drupal themes, the information related to the date and the author of a node is displayed trough the $submitted variable located in the node.tpl.php file.

When we are porting a theme from a graphic file or from another template, sometimes it is necessary to alter the node information. If these modifications implicate a change of date format or the addition of new data, then these changes can't be achieved by just touching the CSS file.

This tutorial is a simple example of how to alter the standard Drupal node variable $submitted to accommodate the new requirements.

We are going to work on a GPL theme named One Room. This theme is a Free Wordpress template so we are not breaking any rules here. If we take a look at this theme we'll see that, in relationship with Drupal themes, there are several differences in the way that the node information is displayed.

So this is the way that the node info is showed in our standard Drupal theme:

and this is our goal after the changes:

List of the changes we need to do:

  • Date format
  • Add info about the number of comments
  • CSS adjustments

The variable "$submitted"

Looking trough the documentation in the Drupal API, we find the function that generates the $submitted variable output.



to alter this output it is necessary to override theme_node_submitted function from the template.php file.

One thing to note is that because we are porting from a template, we can use the HTML structure as a guide for our modifications. Another advantage is that if we keep the classes and the id's from the original HTML then it is possible to use the original CSS code with almost no changes.

Original HTML code

<div class="postmetadata">
    <p class="meta-date">
        <span class="date-day">4</span>
                <span class="date-month">Feb</span>
        <span class="date-year">2009</span>
         </p>

         <p class="meta-author">by Jeeremie</p>

         <a href="http://...">69 Comments</a>               
     <p class="meta-categories"><a href="http://...">Animals</a>,  <a href="http:...">Nature</a></p>

         <p class="meta-tags"><a href="http://...">Animals</a>, <a href="http://...">Monkey</a>, <a href="http://...">Nature</a></p>
           
</div>

Overriding the output for the $submitted variable.
Inside the template.php file write the function that is used to create the new output. At first we take care of the date:

function mytheme_node_submitted($node){
  $output = '<p class="meta-date">';
  $output .= '<p class="date-day">'. format_date($node->created, 'custom','d') .'</p>';
  $output .= '<p class="date-month">'. format_date($node->created, 'custom','M') .'</p>';
  $output .= '<p class="date-year">'. format_date($node->created, 'custom','Y') .'</p>'; 
  $output .= '</p>';
}

now we handle the information about the node author:

$output .= '<span class="meta-info meta-author">'. theme('username', $node) .'</span>';

now it is time for the comments counter, in this case we use the format_plural function, this function takes care of separate the text between "comment" and "comments".

  if($node->comment_count ){
    $title = format_plural($node->comment_count, t('1 comment'), t('@count comments'));
    $comment_link = l($title, 'node/'. $node->nid, array('fragment' => 'comments'));
    $output .= '<span class="meta-info meta-comments">'.  $comment_link .'</span>';
  }


if we print the comments inside the node info area, is very possible that we want to remove this text from the node links section, so this is not displayed twice in our page. This task can be achieved from the preprocess node function, this function must be located in the template.php file as well.

 $links = $vars['node']->links;
  //looks inside the links array for the comment counter
  //and removes it
  foreach($links as $module => $data){
    if($module == 'comment_comments'){
      unset($links[$module]); 
    } 
  }
  //se vuelve  a armar la variable $links
  $vars['links'] = theme('links', $links);


finally it is time to split the node terms by vocabulary, there is an excellent tutorial about this in the 11 Heavens site, so the code will be like this.

$output .= '<div class="meta-terms">'. $terms .'</div>';

The split_node-terms function groups the node terms according to the vocabulary they belong to.

function mytheme_terms($taxonomy){

if($taxonomy && module_exists('taxonomy')){ 

  foreach($taxonomy as $term){
    // We will build a new array where there will be as many
    // nested arrays as there are vocabularies
    // The key for each nested array is the vocabulary ID.    
    $vocabulary[$term->vid]['taxonomy_term_'. $term->tid]  = array(
      'title' => $term->name,
      'href' => taxonomy_term_path($term),
      'attributes' => array(
    'rel' => 'tag',
    'title' => strip_tags($term->description),
      ),
    );  
  }
  // Making sure vocabularies appear in the same order.
  ksort($vocabulary, SORT_NUMERIC);
 

  // And build a new $terms.
  foreach ($vocabulary as $vid => $terms) {
    // Getting the name of the vocabulary.
    $name = taxonomy_vocabulary_load($vid)->name;
    // Using the theme('links', ...) function to theme terms list.
    $terms = theme('links', $terms, array('class' => 'links inline'));
    // Wrapping the terms list.
    $output['terms'] .= '<div class="meta-info vocabulary taxonomy_vid_';
    $output['terms'] .= $vid;
    $output['terms'] .= '">';
    $output['terms'] .= '<span class="vocabulary-name">'. $name;
    $output['terms'] .= ':&nbsp;</span>';
    $output['terms'] .= $terms;
    $output['terms'] .= '</div>';
  }
  return $output;

}

}


Merging all parts the mytheme_node_submitted function will look like this

function mytheme_node_submitted($node){
      $new_terms = split_node_terms($node->taxonomy);
      $terms = $new_terms['terms'];
    <p class="meta-date">
        <span class="date-day">'. format_date($node->created, 'custom','d') .'</span>
                <span class="date-month">'. format_date($node->created, 'custom','M') .'</span>
        <span class="date-year">'. format_date($node->created, 'custom','Y') .'</span>
        </p>
    <p class="meta-author">by '. theme('username', $node) .'</p>
  if($node->comment_count ){
    $title = format_plural($node->comment_count, t('1 comment'), t('@count comments'));
    $comment_link = l($title, 'node/'. $node->nid, array('fragment' => 'comments'));
    $output .= '<span class="meta-comments">'.  $comment_link .'</span>';
  }
  $output .= '<div class="meta-terms">'. $terms .'</div>';

  return $output; 
}

And finally the CSS stuff. If we did the things right and keep the classes and id's from the original template this is just a case of copy and paste.

Notes:
Inside of the $submitted variable are rendered the node terms. In order to avoid displaying twice the node taxonomy, it is necesary to remove the $terms variable from the node.tpl.php file.

Conversation

Permalink

Thanks a lot!! It was very useful.