Saturday, April 9, 2011

Converting Drupal themes from Drupal 6 to Drupal 7

Blocks have new, more meaningful CSS IDs

I’d say it’s about time this happened. Core CSS block IDs now have more meaning that relates to their functionality.
Some examples:
Recent blog posts
Old CSS ID (Drupal 6): block-blog-0
New CSS ID (Drupal 7): block-blog-recent
Recent comments
Old CSS ID (Drupal 6): block-comment-0
New CSS ID (Drupal 7): block-comment-recent

** n.b: If you like this article, then please click on any one of the ad links on the top or side panel. Your small help will encourage me to deliver more useful and good tutorial resources for Drupal in this blog. **

HTML classes generated through a variable

This is something I used to patch into my node.tpl file & preprocess_node hook but now it has been included in core.
Each template (.tpl file) now has a $classes variable which now gives themers a standard way to add HTML classes to their template files:

print $node->nid; ?>" class="print $classes; ?> clearfix"print $attributes; ?>>
.....
The $classes variable can be added to in your preprocess hooks using the $classes_array:
/**
* example taken from core bartik theme
*/
function bartik_preprocess_block(&$variables) {
 
// Set "first" and "last" classes.
 
if ($variables['block']->position_first){
   
$variables['classes_array'][] = 'first';
  }
  if (
$variables['block']->position_last){
   
$variables['classes_array'][] = 'last';
  }
 
// Set "odd" & "even" classes.
 
$variables['classes_array'][] = $variables['block']->position % 2 == 0 ? 'odd' : 'even';
}
?>

HTML attributes generated through a variable

Now all template (.tpl) files can output 3 new variables; $attributes, $title_attributes, and $content_attributes which like the $classes variable mentioned above can be altered or added to in your preprocess functions.

Nice additions to drupal_add_css() function

The drupal_add_css() function is used to attach CSS files to pages and the following functionality has been added:
  • ‘weight’ – You can now weight your CSS file loading although I can’t think of too many times when you’d need this.
  • ‘browsers’ – You can now browser-targeted your CSS files, so you can easily add IE CSS fixes without needing to add code to your templates, which is great in my opinion.

Variable process functions can now be used for all theming hooks

Previously you could only use preprocess functions (called before the theme template to add/alter variables that go into the .tpl file) in your theme when a .tpl file was defined for the theme function output:
template (.tpl) file:


  echo $some_custom_var; ?>

Related hook_preprocess:
function THEME_preprocess_HOOK(&$vars) {
  if (.....) {
   
$vars['some_custom_var'] = t('Hi there');
  }
}
?>
BUT now all theme hooks can have a hook_preprocess and a new hook_process (see notes on that below) which can be used to add new variables & alter current variables which are passed to the define theme function:
theme_ function:
function theme_something_nice()
 
$output = $some_custom_var;
  return
$output;
}
?>

Related hook_preprocess:
function THEME_preprocess_HOOK(&$vars) {
  if (.....) {
   
$vars['some_custom_var'] = t('Hi there');
  }
}
?>

Function names must match theme name

This will save a fair bit of confusion! When overriding module theme functions in your theme you can no longer use the phptemplate_ prefix and instead have to use the name of your theme as a prefix instead:
Drupal 6:
/**
* both examples work in Drupal 6
*/
function phptemplate_breadcrumb() {
......
}
?>
Drupal 7:
function THEMENAME_breadcrumb() {
.....
}
?>
Read more on why the phptemplate prefix was removed.

Granular rendering in node and user templates

Ever hacked up your node.tpl.php file and print bits of the $node object all over the place to get the content layout exactly as you want? Well with the new render & hide functions things just got a little easier!!
The $content variable is now a keyed array of the content values including field values, comments, file attachments or other node components which vary depending on the view mode (full, teaser etc). If you’d like to go deeper check out the the node_build_content API doc on api.drupal.org
Here’s an example from the Garland theme node.tpl.php file, as you can see the node links & comments can be pulled out and rendered as where you please:
 
print $content_attributes; ?>>
          // We hide the comments and links now so that we can render them later.
     
hide($content['comments']);
     
hide($content['links']);
      print
render($content);
   
?>

 


 

    if (!empty($content['links'])): ?>
     
    endif; ?>

    print render($content['comments']); ?>
 

Alter hooks available to themes!!

This is by far my favourite addition.
The following alter hooks have now be added or made available to use in your themes:
  • hook_page_alter – This is a new D7 hook which allows all variables displayed on a page to be alter or hidden.
  • hook_form_alter – I’ve lost count of how many times I’ve wanted to make a small tweak to a form without wanting to override the form theme or create a custom module.
  • hook_js_alter
These additions give even more power to Drupal theme developers which is brilliant news!! :) :)

Theme suggestions available for theme_menu_link() and theme_menu_tree()

I’ve previously used the awesome menu_block module to theme out menus better as it uses a similar theme suggestion engine that is now available in Drupal 7.
The new suggestion work for both theme_menu_tree which provides some wrapper HTML for the menu and theme_menu_link which does the actual rendering of the menu link, so you can override these functions per menu.
Here’s a simple example for a theme_menu_link override for a fictional user called “account” where we simply add an extra around the link to give us another HTML element to theme with:
function THEMENAME_menu_link__account($variables) {
 
$element = $variables['element'];
 
$sub_menu = '';

  if (
$element['#below']) {
   
$sub_menu = drupal_render($element['#below']);
  }
 
$output = ''. l($element['#title'], $element['#href'], $element['#localized_options']) .''; //add extra span tag here for theming
 
return '. drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "\n";
}
?>

hook_preprocess is now followed by hook_process

I’m still a little hazy on the exact usage of the new hook_process so I wouldn’t consider it a favourite of mind….yet but I thought it should be mentioned.
The idea is that hook_preprocess is run first to define values of variables then hook_process is fired after to render variables.
An example being the $classes_array is defined/constructed in hook_preprocess and is then rendered into the $classes string in hook_process.
That concludes my favourite additions to Drupal 7 theming but please note that with Drupal 7 still being developed some of this functionality could (although unlikely) change so comment below if you find something has changed or add your favourite additions.

6 comments:

  1. Code reference was really good and an useful post for a Drupal beginners!

    ReplyDelete
  2. This is great to read and I appreciate it that you shared handy post . I will keep this post in mind.

    ReplyDelete
  3. Excellent article above. May be you need more time to share all the knowledge that you have.
    So, thanks for share this information with us, I always come across this amazing post.

    ReplyDelete
  4. Good work , keep us posting , your a very good writer...
    Nice site , Very Intresting post. Thank you .

    ReplyDelete
  5. Excellent new topics, always interesting to read articles that are relevant to the topic, thanks for all the great news and responses.

    ReplyDelete
  6. Great converting information for drupal 6 to drupal 7.


    ReplyDelete