Skip to main content

Having a node's field show in a block region.

I'm currently building a website that has a three columned layout. The left most column contains the navigation elements, the center column contains the body, and the right side column contains supporting text for the article. So I created three block regions in my theme: left_sidebar, content, and right_sidebar. The problem I ran into was that the text in the right side column was different for every node. Having the user create a separate block for each node seemed very inefficient. So I thought, what if I can have a field on a node that gets displayed in the right_sidebar block region?

Displaying a field in a block region

To accomplish this, I used the template_preprocess_page() function. First, we check for the existence of the field:

  1. if(isset($vars['node']->field_general_information) && $vars['node']->field_general_information['und'][0]['safe_value']) {

Next, we programmatically create a new block using the value the user entered on the node form
  1. $right_sidebar = array(
  2.         'general_information' => array(
  3.           '#markup' => $vars['node']->field_general_information['und'][0]['safe_value'],
  4.           '#theme_wrappers' => array('block'),
  5.           '#block' => (object)array(
  6.             'module' => 'MYTHEME',
  7.             'delta' => 'general-information',
  8.             'region' => 'right_sidebar',
  9.             'theme' => 'oassa',
  10.             'subject' => FALSE,
  11.           ),
  12.         ),
  13.       );

Finally, we add our newly created block to the right_sidebar region
  1.  // If the right_sidebar region is already populated, add our new block to the beginning of the region.
  2.       if(!empty($vars['page']['right_sidebar'])) {
  3.         array_unshift($vars['page']['right_sidebar'], $right_sidebar);
  4.       }
  5.       else {
  6.         // If the right_sidebar doesn't exist, add our new region. 
  7.         $vars['page']['right_sidebar'] = $right_sidebar;
  8.       } 

This makes it easier for the end user by being able to edit a block on the node page, while still giving us the ability to add blocks to the region. Brilliant!

The full code

  1. function MYTHEME_preprocess_page(&$vars){
  2.   // Check to see if we are on a node page.
  3.   if(isset($vars['node'])) {
  4.     // Check to see if the field we want to display is setup and contains content
  5.     if(isset($vars['node']->field_general_information) && $vars['node']->field_general_information['und'][0]['safe_value']) {
  6.       // Create an array with the safe_value taken from the node object for our field.
  7.       $right_sidebar = array(
  8.         'general_information' => array(
  9.           '#markup' => $vars['node']->field_general_information['und'][0]['safe_value'],
  10.           '#theme_wrappers' => array('block'),
  11.           '#block' => (object)array(
  12.             'module' => 'oassa',
  13.             'delta' => 'general-information',
  14.             'region' => 'right_sidebar',
  15.             'theme' => 'oassa',
  16.             'subject' => FALSE,
  17.           ),
  18.         ),
  19.       );
  20.  
  21.       // If the right_sidebar region is already populated, add our new block to the beginning of the region.
  22.       if(!empty($vars['page']['right_sidebar'])) {
  23.         array_unshift($vars['page']['right_sidebar'], $right_sidebar);
  24.       }
  25.       else {
  26.         // If the right_sidebar doesn't exist, add our new region. 
  27.         $vars['page']['right_sidebar'] = $right_sidebar;
  28.       } 
  29.     }
  30.   }
  31. }


Comments