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

Profile picture for user Phil Frilling
By Phil Frilling, 4 May, 2012
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:

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

$right_sidebar = array(
        'general_information' => array(
          '#markup' => $vars['node']->field_general_information['und'][0]['safe_value'],
          '#theme_wrappers' => array('block'),
          '#block' => (object)array(
            'module' => 'MYTHEME',
            'delta' => 'general-information',
            'region' => 'right_sidebar',
            'theme' => 'oassa',
            'subject' => FALSE,
          ),
        ),
      );
Finally, we add our newly created block to the right_sidebar region

 // If the right_sidebar region is already populated, add our new block to the beginning of the region.
      if(!empty($vars['page']['right_sidebar'])) {
        array_unshift($vars['page']['right_sidebar'], $right_sidebar);
      }
      else {
        // If the right_sidebar doesn't exist, add our new region. 
        $vars['page']['right_sidebar'] = $right_sidebar;
      } 
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


function MYTHEME_preprocess_page(&$vars){
  // Check to see if we are on a node page.
  if(isset($vars['node'])) {
    // Check to see if the field we want to display is setup and contains content
    if(isset($vars['node']->field_general_information) && $vars['node']->field_general_information['und'][0]['safe_value']) {
      // Create an array with the safe_value taken from the node object for our field.
      $right_sidebar = array(
        'general_information' => array(
          '#markup' => $vars['node']->field_general_information['und'][0]['safe_value'],
          '#theme_wrappers' => array('block'),
          '#block' => (object)array(
            'module' => 'oassa',
            'delta' => 'general-information',
            'region' => 'right_sidebar',
            'theme' => 'oassa',
            'subject' => FALSE,
          ),
        ),
      );
      
      // If the right_sidebar region is already populated, add our new block to the beginning of the region.
      if(!empty($vars['page']['right_sidebar'])) {
        array_unshift($vars['page']['right_sidebar'], $right_sidebar);
      }
      else {
        // If the right_sidebar doesn't exist, add our new region. 
        $vars['page']['right_sidebar'] = $right_sidebar;
      } 
    }
  }
}