Drupal coder

theming

Theme variables available to all Drupal template files

When writing themes there's a few values we frequently need to access in our templates. I'm thinking about stuff like "is the user logged in", "is the user an admin", "what is the theme directory" (for referencing images etc)?

The good news is that all these and a few more are available in all template files. Here's a listing of what variables are available and how you can add your own.

May 14, 2010Drupal, theming

Overriding theme_blocks when using Block Translation module (i18n)

I just pulled my hair out looking for what caused this, but eventually found it after scanning the module files. The issue was that overriding hook_theme_blocks wasn't possible in some theme. The version in the theme wouldn't get called at all, even after rebuilding the theme registry by clearing the cache. The culprit was the Block Translation module.

February 18, 2010Drupal, i18n, theming

Overriding CSS stylesheets in Drupal themes

Some modules do provide their own CSS files. Themers might not always like what's happening in there and want to provide their own styles. You can remove the file (using preprocessing) or you can just replace the file with your own in your theme.

An example? Take the link module, which adds a link field type to CCK. This module has provides a CSS file : link.css. Suppose you have uploaded your module at sites/all/modules/contribute/link, we now have a file sites/all/modules/contribute/link/link.css.

January 13, 2010Drupal, theming

Showing left and right region on page not found

Drupal has it's own system to handle "Page not found" errors. It uses a simple function, called drupal_not_found to set the correct headers, etc. That function calls theme_page to do its rendering.
The catch here is that it calls theme_page with the $show_blocks argument set to FALSE. This means blocks in the left and right columns won't be shown here.

// To conserve CPU and bandwidth, omit the blocks.
print theme('page', $return, FALSE);

In some cases, you might not want this behavior. You might have your navigation in one of these sidebars and you want to give your visitors some way out of this page. The navigation might get the person back on track.

How can we fix this? Very simple. Put the following code in your page preprocessing function.

function phptemplate_preprocess_page(&$variables) {
  // show all regions if page not found
  $page_not_found = strpos(drupal_get_headers(), 'HTTP/1.1 404 Not Found') !== FALSE;
  if (!$variables['show_blocks'] && $page_not_found) {
    global $theme;
    // Populate all block regions.
    $regions = system_region_list($theme);
    // Load all region content assigned via blocks.
    foreach (array_keys($regions) as $region) {
      // Prevent left and right regions from rendering blocks when 'show_blocks' == FALSE.
      if ($region == 'left' || $region == 'right') {
        $blocks = theme('blocks', $region);
      }
      // Assign region to a region variable.
      isset($variables[$region]) ? $variables[$region] .= $blocks : $variables[$region] = $blocks;
    }
  }
}

This will only render the left and right blocks, the other ones are already rendered by Drupal core.

February 15, 2009Drupal, theming

Setting the date result of search results to the node creation date

The date Drupal shows on search results is not the date the node was created. Instead it is the date the node was indexed by the search indexer.
Most of the time this is the wanted behavior. Your nodes get indexed when cron is run and if you run cron each 5 or 15 minutes this date is within 15 minutes of the creation date.

But the date is far off when import your nodes from another system. Sometimes this date has been created years ago, and then the time between creation and indexing is long.

As always there's an easy fix for this in Drupal. The search results are themed via theme_search_item and we all know how to override a theme function.

We just have to change

  if ($item['date']) {
    $info[] = format_date($item['date'], 'small');
  }

to

  if(isset($item['node'])) {
  	$info[] = format_date($item['node']->created, 'small');
  } elseif ($item['date']) {
    $info[] = format_date($item['date'], 'small');
  }

So we get:

function phptemplate_search_item($item, $type) {
  $output = ' <h3><a href="'. check_url($item['link']) .'">'. check_plain($item['title']) .'</a></h3>';
  $info = array();
  if ($item['type']) {
    $info[] = check_plain($item['type']);
  }
  if ($item['user']) {
    $info[] = $item['user'];
  }
  /*if ($item['date']) {
    $info[] = format_date($item['date'], 'small');
  }*/
  if(isset($item['node'])) {
  	$info[] = format_date($item['node']->created, 'small');
  } elseif ($item['date']) {
    $info[] = format_date($item['date'], 'small');
  }
  if (is_array($item['extra'])) {
    $info = array_merge($info, $item['extra']);
  }
  $output .= ' <div>'. ($item['snippet'] ? '<p>'. $item['snippet'] .'</p>' : '') .'<p class="search-info">'. implode(' - ', $info) .'</p></div>';
  return $output;
}
October 12, 2008Drupal, search, theming