Drupal 7 theming basics

Dec 17 2009

Drupal 7 theming basics

Posted by amandar

I am no expert on Drupal theming, but I recently attempted to convert one of my Drupal themes to Drupal 7 and it was pretty stressful at times! I'm gonna try and outline some of my changes here. The theme I am attempting to update is http://www.drupal.org/project/orange/

.info files

.info files have changed. The content variable has been removed for Drupal 7, so you need to declare the region in your .info file or you wont even be allowed to enable the theme. Also because of problems with sub-theming style.css is no longer added by default. You will need to also declare this in your .info file.
Like Drupal 6 if you want custom regions and js files you declare them here as usual.

<?php
regions
[content] = Content
stylesheets
[all][] = css/style.css
?>

page.tpl.php

Page.tpl.php has some changes, for one you no longer have to have html head or body tags. This data is contained in a the page variable. Regions are also in the page variable. At the top of your page.tpl.php you'll see:

<?php print render($page['header']); ?>

At the bottom you'll see:

<?php print render($page['footer'); ?>

To check if a region has content and print out (which was really hard for me to realize at first!) you do the following:

<?php if ($page['sidebar_first']): ?>
<?php print render($page['sidebar_first']); ?>
<?php endif; ?>

template.php

So I had to make a few changes here. First off my breadcrumb, previously was:

<?php
function orange_breadcrumb($breadcrumb) {
  if (!empty(
$breadcrumb)) {
   
$breadcrumb[] = drupal_get_title();
   
$separator = theme('image', drupal_get_path('theme', 'orange') .'/images/black-bullet.gif');
    return
'<div class="breadcrumb">'. implode(' '. $separator .' ', $breadcrumb) .'</div>';
  }
}
?>

the theme function has changed, this took me a WHILE to figure out... so to get the same result I have the following for D7:

<?php
function orange_breadcrumb($variables) {
 
$breadcrumb = $variables['breadcrumb'];
 
$output = '';
  if (!empty(
$breadcrumb)) {
   
$breadcrumb[] = drupal_get_title();
   
$separator = theme('image', array('path' => path_to_theme() . '/images/black-bullet.gif'));
   
$output .= '<div class="breadcrumb">' . implode(' '$separator .' ', $breadcrumb) . '</div>';
    return
$output;
  }
}
?>

Drop down menus

This was probably the hardest task for me but I managed to figure it out in the end. In the Drupal 6 theme I had the following in my preprocess_page function to achieve a drop down:

<?php
if ($vars['primary_links']) {
 
$pid = variable_get('menu_primary_links_source', 'primary-links');
 
$tree = menu_tree($pid);
 
$tree = str_replace(' class="menu"', '', $tree);

 

$vars['primary_links'] = '<del class="wrap">'. $tree .'</del>';
}
?>

Primary links have been renamed to main menu in D7. So we have to alter this, also printing the $tree variable just gives you "Array" so you need to use drupal_render to have it appear. This is what I ended up with for D7:

<?php
if (isset($vars['main_menu'])) {
 
$pid = variable_get('menu_main_links_source', 'main-menu');
 
$tree = menu_tree($pid);
 
$tree = str_replace(' class="menu"', '', $tree);
 
$vars['primary_nav'] = drupal_render($tree);
}else{
 
$vars['primary_nav'] = FALSE;
}
?>

Thats all I've got so far! I'll post more struggles as they come. If I am doing anything wrong here, by all means correct me!

Comments

Shannon's picture

Spent three hours tearing my hair out trying to get menu dropdowns in a D7 theme (and I didn't want to use a module), and out of Google searches of posts full of failed code after failed code, I finally find something here that actually *WORKS* (with a little modification). Thank you much.

Ron's picture

First off really nice site, and very nice post.

I can across this via some googling, working on a D7 set up myself.
I am trying to check weather or not a region has content on that page and show some extra markup depending on that fact.

so I grabbed this set up from one of the core themes, as you posted:
<?php if ($page['sidebar_first']): ?>            <?php print render($page['sidebar_first']); ?><?php endif; ?>

and I changed it to something like this:
      <?php print render($page['sidebar_first']); ?><?php if ($page['sidebar_first']): ?>      show some other stuff<?php endif; ?>

but no matter what the 'show some other stuff' always pops up, am I missing more things simple here?

Ron's picture

Had some trouble formatting the code in the post, or at least the preview looked odd, hope this makes sense...

First off really nice site, and very nice post.

I can across this via some googling, working on a D7 set up myself.
I am trying to check weather or not a region has content on that page and show some extra markup depending on that fact.

so I grabbed this set up from one of the core themes, as you posted:

<?php if ($page['sidebar_first']): ?><?php print render($page['sidebar_first']); ?><?php endif; ?></cod>and I changed it to something like this:<code><?php print render($page['sidebar_first']); ?><?php if ($page['sidebar_first']): ?>      show some other stuff<?php endif; ?>

but no matter what the 'show some other stuff' always pops up, am I missing more things simple here?

Tina's picture

Nice! It works so far for displaying the primary links (after hours of Google as well... thanks for that!), but it doesn't display any submenu, it's not even in the html. Same problem with the Garland theme btw... Am I missing something essential?

amandar's picture

the problem is that you're printing the sidebar_first without checking to see if it exists first, so by the time you get to checking if it exists, it does. It will always exist. you should move the if statement so it wraps around the sidebar and the extra stuff.

amandar's picture

Oh man to be honest Tina, I wrote this post SO long ago and have since used a different way to show drop downs... :/ it could be that something was changed in core that would make this not work.

Perhaps check to see that the source for your secondary links is set to primary links in menus -> settings.

Brady Jacobsen's picture

"To check if a region has content and print out (which was really hard for me to realize at first!) you do the following:"
-Thanks!

m3n0R's picture

Hi !

I'm really interested in your theme for Drupal 7. I'm attempting to develop my own Blow, and when I was searching themes I saw yours is the one which fits better for my Blog. I'm a Drupal developer, if I can help you with something just tell me. When are you going to launch the Drupal 7 version of the theme?

Thank a lot!

Richard's picture

Thanks very much I have spend hours trying to fix menu in page.tpl but always got Array printed. The drupal_render did the trick.

Thanks very much

Web Design Karachi's picture

Is there a way to print field_something into page.tpl.php file.

amandar's picture

yes, you have to load the node object into your preprocess page function. It looks something like this:

<?php
/**
* Prepreprocess function for page.tpl.php.
*/
function mytheme_preprocess_page(&$vars) {
if(
is_object($vars['node'])) {
       switch (
$vars['node']->type) {
         case
'mycontenttype':
          
$node = $vars['node'];
          
$vars['myfield'] = $node->field_my_field[0]['value'];
         break;
       }
     }
}
?>

Hope this helps!!

Sean's picture

And here I was believing all the hype over Mollom... Anyway, the snippet you have for the menu doesn't work for me. You mentioned you do something different now...

amandar's picture

Sean I usually just have a special navigation region and throw a menu block in there and style the drop downs myself using simple JS to make the drop downs show. (basically when you hover on a link with a nested ul give it the class 'hover' and then in css made that display block) No need to get all fancy.

Add new comment