How to Customize Your Drupal Theme and Make it More Blog Friendly in 9 Easy Steps

Over the weekend, I redesigned the theme of my blog. I hope you like the result!

While I'm not a web design nor a theming expert, it was still quite easy to find a nice theme, and apply some blog-friendly customizations to it. Here are a few tips to get you started in Drupal theming:

1. You're a Blogger, not a Designer. Start With a Pre-Built Theme!

New Blog DesignReally. If you're not an artist, don't ruin your blog with a clumsy theme. There are so many ready-to-use Drupal themes, you're very likely to find one that appeals to you.
If in doubt, go for simplicity. After all, you want your readers to concentrate on the content, not some flashy coloring. I was very impressed by the Drupal Zen Theme, which is really a template for sub-themes, but very simple, yet nicely done and conforming to standards (things that quality geeks value and designers should respect).
In fact, this theme has spun off a following of its own, including many other themes based on it.
And there it was: Among the current list of Zen Sub-Themes, I found the CTI Flex theme by Andrea Ross. Simple, yet beautiful and nicely customizeable!
Of course, taste varies, so check out other theming resources and find your perfect theme for yourself.

2. Always Test Your Theme Behind the Scenes

A good way to test themes without your blog users noticing is to give your admin user the permission to choose a theme, and any anonymous (or other users) not. That way, you can fully test your new theme without your readers noticing how much is broken and still needs to be fixed.

It goes without saying that you should have an escape plan in case your theming experiments go horribly wrong: Back up your site and know how to restore it, just in case. It also helps to have a second user that has admin rights and can pull your real admin user out of trouble. Or remove the broken theme in case of an emergency, so that Drupal reverts to a default one so you can regain control if needed.

When tweaking themes, keep in mind that some changes may not reflect right away. You'll need to reset Drupal's cache in order to see some modifications. Check out Drupal's theming guide for details.

Thanks to Andreas for pointing out this easy way to test without your readers noticing!

3. Subtheme an Existing Theme, then Customize...

Drupal themes support sub-theming. This is a cool way to save effort. It works like inheritance in object-oriented languages: Install a theme, set up your sub-theme, then only change the bits that you want to differ, the rest will be inherited from the parent theme. This even works across multiple levels of hierarchy.
Here's a nice guide for you: Subtheming Quick and Dirty. I used this to subtheme my last theme from the default "Garland" theme and it worked very well for me.
There are some subtleties in the things that can be inherited vs. then things you'll nee to copy over to your subtheme. If that's not for you, read on:

4. ...or Modify an Existing Theme

Sometimes subtheming doesn't work well. Some things may be inherited properly, some things may not. Or sometimes it's too complicated to keep track of inherited stuff and you want more control. Then, take an existing theme and modify it (if its license allows you to).

In my case, the CTI Flex theme didn't subtheme properly (probably because of my lack of experience :) ) so I just made a copy of it and modified it according to my needs.

Remember to give your theme a new name by renaming its directory and its .info file. You may also want to rename any variables in the PHP code to reflect your new theme name.

5. Apply Some Basic Theme Modifications

A good theme is strictly divided between structure (the logic that places bits of content on the page, using HTML and JavaScript) and appearance (the style applied to the content, using CSS).

When modifying or adapting a sub-theme, start with the CSS files and adjust them to your needs. This could be colors, fonts or size values, etc.

In my case, I wanted the right column to have a size consistent with the golden ratio, so I could have more space there and still have an overall harmonic feeling to the page.

I also tweaked the footer color to be lighter, so the imprint link doesn't look awkward.

CSS isn't hard to learn. If you've seen a programming language before, you'll quickly grasp the concepts. Here's a very nice CSS cheat sheet to help you out.

6. Try Out More Advanced Theme Modifications

If you want to change something more fundamental, you'll need to get your hands dirty and hack some PHP.

Again, if you've seen a programming language before, you'll probably know your way around PHP pretty fast. And the great thing about modifying an existing theme is that somebody has done most of the work already and you just need to apply some modifications here or there or copy/past some bits of code to get where you want.
And yes, there's also a nice PHP cheat sheet available as well.

The following sections will discuss some modifications that I think are particularly useful to bloggers.

7. How to Get Rid of RSS Icons

Drupal has the habit of putting RSS icons everywhere. I find that distracting, especially for a blog where you typically want to send your users to a single RSS feed (or a predefined, limited set of RSS feeds) for the whole blog.

So the first thing I did to the CTI Flex theme was removing the default RSS icon. This can be done by tweaking the page.tpl.php file. Find the line that uses the $feed-icons variable and tweak it (or remove it altogether).

But that wasn't very nice of me, so I though I'd rather make it customizable. This can be done by introducing a new configuration variable in the theme's info file:

settings[ct_2_show_rss_icons] = 1

Then you can add a configuration block to the theme-settings.php file:

$form['ct_2_show_rss_icons'] = array(
  '#type'          => 'checkbox',
  '#title'         => t('Show RSS icons on pages'),
  '#default_value' => $settings['ct_2_show_rss_icons'],
  '#description'   => t('Uncheck this if you want to place your own RSS icons/links.'),
  '#prefix'        => '<fieldset class="collapsible"><legend>Custom page element settings</legend><br />These settings specify elements and how they should be rendered on pages.<div style="margin: 20px 0 0 20px;"><b>RSS Settings</b>',
);

Now you can choose if you want RSS icons to show up in pages or not in the theme settings configuration page. Neat!

But you still need to tweak the page template to honor the setting. There's a better place than page.tpl.php to do this: template.php handles all pre-processing for your theme in a central file. Here, we can just shut down the $feed-icons variable if we don't want it, depending on our newly introduced setting:

if (theme_get_setting('ct_2_show_rss_icons') == '0'){
    $vars['feed_icons'] = "";
}

This is best done inside the preprocess_page() function (you'll need to create it if it doesn't exist yet).

8. Separating Tags From Categories

One of the peculiarities of Drupal is that it's tagging system is very generic: The taxonomy module allows you to create multiple "dictionaries", and each dictionary can have multiple "terms" along with rules on how to use them.
"Tags" in a blog sense, are to Drupal just a dictionary called "Tags" that can be expanded with each post. And blog "Categories" are another dictionary where you can choose just one term per blog post.

This is all cool, but when displaying a page, Drupal mixes all terms for that page together into one long string. There's no separation of tags from categories in typical Drupal themes.

Fortunately, I've found a solution for this, along with some PHP code to create separate term lists, sorted by dictionary.
Again, I added a new variable and a configuration block to make it neatly configurable. In the info file:

settings[ct_2_split_terms_by_dict] = 0

In theme-settings.php:

$form['ct_2_split_terms_by_dict'] = array(
  '#type'          => 'checkbox',
  '#title'         => t('Split terms by dictionary'),
  '#default_value' => $settings['ct_2_split_terms_by_dict'],
  '#description'   => t('Check this if you want to separate categories from tags in blog posts.'),
  '#suffix'        => '</div></fieldset>',
);

BTW: The #prefix and #suffix bits in the above pieces of theme-settings.php are meant to work together so both settings appear in their own block.

In template.php, add the term sorting code (this has been taken from Caroline Schnapp's solution in the above Drupal article and adapted to use tables for nicer formatting):

function ct_2_preprocess_node(&$vars) {
  // Sort taxonomy terms by vocabularies if specified.
  if ($vars['node']->taxonomy) {
    if (theme_get_setting('ct_2_split_terms_by_dict') == "1") {
      // Let's iterate through each term.
      foreach ($vars['node']->taxonomy as $term) {
        // We will build a new array where there will be as many
        // nested arrays as there are vocabularies
        // The key for each nested array is the vocabulary ID.
        // Make any html mark-up changes on the terms here
        $vocabulary[$term->vid]['taxonomy-term-'. $term->tid] = array(
            'title' => $term->name,
            'href' => taxonomy_term_path($term),
            'attributes' => array(
            'rel' => 'tag',
            'title' => strip_tags($term->description),
          ),
        );
      }
      // Making sure vocabularies appear in the same order. This line is optional.
      krsort($vocabulary, SORT_NUMERIC); // We want "Categories" (2) to appear before "Tags" (1).
      // We will get rid of the old $terms variable.
      unset($vars['terms']);
      // And build a new $terms.
      $vars['terms'] .= '<table class="taxonomy">';
      foreach ($vocabulary as $vid => $terms) {
        // Getting the name of the vocabulary.
        $name = taxonomy_vocabulary_load($vid)->name;
        // Using the theme('links', ...) function to theme terms list.
        $terms = theme('links', $terms, array('class' => 'links inline'));
        // Wrapping the terms list.
        // Make any html mark-up changes on vocabulary wrapping here.
        $vars['terms'] .= '<tr><div class="meta taxonomy-vid-';
        $vars['terms'] .= $vid;
        $vars['terms'] .= ' taxonomy-';
        $vars['terms'] .= $name;
        $vars['terms'] .= '"><td class="taxonomy-dict">';
        $vars['terms'] .= $name;
        $vars['terms'] .= ':</td><td class="taxonomy-terms">';
        $vars['terms'] .= $terms;
        $vars['terms'] .= '</td></div></tr>';
      }
      $vars['terms'] .= '</table>';
    } else {
      // Add the word "Tags: " to the terms variable.
      $vars['terms'] = 'Tags: ' . $vars['terms'];
    }
  }
}

Don't forget to add some CSS styling so the tags/category block look nice. In this case, I applied the same style as the author information in the main CSS file, plus some alignment rules:

.taxonomy-dict {
    color: #888;
    vertical-align: top;
    text-align: right;
}
 
table.taxonomy {
	width: auto
}

It looks harder than it really is. Just start playing with the code and see if you can get it to do what you want. Of course, googling and browsing the Drupal website help a lot, too.

9. Conclusion And A Download Link For You

See, that wasn't to hard, was it? If you want to try out my modified them for yourself, feel free to download it and give it a shot. I called it "Constant Thinking 2", because it's the second theme that I modified for this blog according to my needs.

Again, many thanks to Andrea for designing the CTI Flex theme in the first place, I just added the above tweaks to make it more blog friendly.
All modifications are commented in the corresponding files and the README containes a list of the files I tweaked as well as a summary of new features.

Your Turn

Did you do some theming work for Drupal so far? What are your experiences? What did you modify in your theme to make it more blog friendly? Feel free to add a comment and share your experience!

Related Posts

Edit: Small fix to the table formatting (thx to Andreas!) and proper crediting of the Drupal article that provided the taxonomy code.

Stay in Touch!

Did you like this article? Have you found it useful, interesting or entertaining?

Then click here to get free regular updates and help me reach my goal of 1,000 regular blog readers this summer!

Thank you for reading Constant Thinking.