Adding multiple sidebars (and other elements) to your wordpress theme

Wordpress LogoUpdate: Marquex has written a plugin that takes care of all this without having to touch PHP. Check it out: Custom sidebar WordPress plugin

I’m going to show you (you, being the wordpress theme developer or modifier) how to add elements to your blog that will change based on which page you are on. A great example of this is changing which button is on for your navigation to indicate which section is currently active. I will also show you how to get multiple widgetized sidebars rocking for your theme. I’m going to make the assumption that you already know what wordpress pages are and how wordpress can act as a cms. I will also assume you know how to widgetize your theme. Onwards.

Creating multiple dynamic sidebars

Let’s take care of a simple task first, creating multiple sidebars. Normally for a standard wordpress theme you will have this function call to register your dynamic sidebar in your theme’s function.php file:

if ( function_exists('register_sidebar') )
register_sidebar();

That needs to go away. The code below allows you to create multiple sidebars and name each one uniquely. Just simply rename ‘sidebar#’ and put in as many sidebars as you like.

if ( function_exists('register_sidebar') ) {
    register_sidebar(array('name'=>'sidebar1'));
    register_sidebar(array('name'=>'sidebar2'));
    register_sidebar(array('name'=>'sidebar3'));
}

Here is an example of wordpress 2.7.1 using multiple sidebars in the widget screen:

Multiple Sidebars With Widets

There is a catch with this. With multiple sidebars, most likely you are going to want to add the same widget to multiple sidebars. Some widgets allow you to have multiple instances of the widget on your sidebar(s). These widgets have a dropdown box in the admin section that allows you to select how many widgets you would like:

Widget Selector

However, most do not. In this case you need to find the php code for the plugin that initializes the widget. You will be looking for the register_sidebar_widget call. For instance, in the delicious cached plugin, I found this function call:

register_sidebar_widget('Delicious Cached++', 'widget_deliciouspp');

All that you need to do is duplicate that line for as many widgets as you need and change the name in the first parameter. My php code now looks like this:

register_sidebar_widget('Delicious Cached++ 1', 'widget_deliciouspp');
register_sidebar_widget('Delicious Cached++ 2', 'widget_deliciouspp');
register_sidebar_widget('Delicious Cached++ 3', 'widget_deliciouspp');
register_sidebar_widget('Delicious Cached++ 4', 'widget_deliciouspp');

Now you should notice your admin interface show multiple instances of the widget like this:

Multiple Widgets

Displaying different sidebars depending what page or subpage you are on

Now comes the fun part. Let’s get those sidebars showing up when you want them to. You’re going to want to add this code to your functions.php file. I won’t explain what it does until the next part (trust me) (also, thanks to Alberto for this post: http://www.altrugon.com/php/get-the-top-parent-page-in-wordpress/)

function getTopParentPostName($myid) {
    $mypage = get_page($myid);

    if ($mypage->post_parent == 0){
        return $mypage->post_name;
    }
    else{
    return getTopParentPostName($mypage->post_parent);
    }
}

function is_tree( $p_name ) {    // $p_name = The page we're looking for pages underneath
    global $post;       // We load this as we're outside of the post
    $top_post_name = getTopParentPostName($post);

    if ( $p_name == $top_post_name ) return true;
    else return false;
}

Now, normally in order to register a dynamic sidebar for your theme, you just do this in sidebar.php (according to wordpress):

if ( function_exists('register_sidebar') )
register_sidebar();

You will be changing it to something like this where main page title # is your main page title name and sidebar# matches your sidebar names as discussed earlier:

if ( is_tree('main page title 1') ) {
    if (!function_exists('dynamic_sidebar') || !dynamic_sidebar( 'sidebar1') ) { $generic_sidebar = true; }
}
elseif ( is_tree('main page title 2')) {
    if (!function_exists('dynamic_sidebar') || !dynamic_sidebar( 'sidebar2') ) { $generic_sidebar = true; }
}
elseif ( is_tree('main page title 3' )) {
    if (!function_exists('dynamic_sidebar') || !dynamic_sidebar( 'sidebar3') ) { $generic_sidebar = true; }
}

Here is what’s happening: the is_tree call checks to see if the current page or subpage you are on is in the family “main page title #”. If it is, then it registers the appropriate sidebar. That’s it! So, sidebars are cool and all, but what about other elements?

Displaying other elements depending what page or subpage you are on

This part is easy now that we’ve got the sidebars done. Let’s use an unordered list for top navigation as an example. I am just adding a class of “over” to the active menu item. You can see that the is_tree function is called again.


34 Comments

  1. Is this your first step by step how-to post? You made it look easy… too easy… easy enough that I might actually try it.

    Reply
  2. Yeah, this is my first one. They’re quite fun to put together. It forced me to put the technicalities into words, something I don’t find easy to do.

    Thanks!

    Reply
  3. Looking good bro.

    Reply
  4. Great how-to Eric! Also, the highlighting is gorgeous.

    Reply
  5. I am having problems getting this to work. I have copied everything you wrote but no sidebar shows, even though my template is widgetized and I added the code you mentioned.

    Reply
  6. Hi Tony,

    So you’re not getting any sidebars to show up? What do you see when you go to the widgets link in the wordpress admin area?

    Reply
  7. Eric,

    After I alter my functions.php file, I get an error that says

    Warning: Cannot modify header information – headers already sent by (output started at /home/newhom5/public_html/wp-content/themes/arras-theme.1.3.5/arras-theme/functions.php:65) in /home/newhom5/public_html/wp-admin/theme-editor.php on line 70

    any ideas?

    Reply
  8. Jayson,

    From what I understand of that error it is most likely caused by extra spaces before or after your php tags. Try this article on wordpress.org that explains the problem.

    Hopefully this helps, and sweet site, by the way.

    Reply
    • I’ve experimented this problem (out of wordpress programming) and in my case the cause of the “extra spaces” in php files (which generate the error “Warning: Cannot modify header information – headers already sent by…” was my desktop code editor (Notepad++), who introduce sometimes the BOM byte at the top of the files for UTF-8 encoded files :S The “BOM byte” is like a non-ASCII character, so… because this reason it is INVISIBLE at the text editor when you open the file!! you only can detect it if you put the cursor just at the beginning of the file using Home key (keyboard) and then you move to the right with “right arrow key”… if the BOM byte exists at your file, then you will see that the cursor DON’T MOVE! 😉 only move with th second press of the “right arrow key”.

      Well, incredible that it occurs!!! :S
      SERGI

      Reply
  9. Eric – thanks for the getting back to me. I’ll check out the article right now.

    Reply
  10. when i use widgets, in other words, when i use functions.php file in theme directiory, some errors happen!!
    like this:
    Warning: Cannot modify header information – headers already sent by (output started at /home/javan/public_html/wp-content/themes/javan-club/functions.php:2) in /home/javan/public_html/wp-login.php on line 287

    or this:
    Warning: Cannot modify header information – headers already sent by (output started at /home/javan/public_html/wp-content/themes/javan-club/functions.php:2) in /home/javan/public_html/wp-includes/pluggable.php on line 689

    can you help me?!plz!!

    Reply
    • Hi Hosein,

      What does your functions.php file look like, especially line 2? Normally this error is caused by code that is attempting to modify the header information of the page after some part of the body in the page has already been sent to the user. This could be as simple as a line break in your functions.php file. Most likely what is going on is functions.php has a line break in the code which would be outputted to the user. Then, any script modifying header information from that point on will cause the error.

      Hope this helps. Feel free to report back your findings. I’m sure it will help others in the future.

      Reply
  11. This looks great. I am more interested in changing the body of my wordpress theme. I have a few games on my site that are much wider that the main column, but I eventually got that butchered enough it fits, but it doesn’t really look good. Any chances of a tutorial on something like that?

    Reply
  12. Thanks Tim for the question. I love being asked questions that could be turned into blog posts. I also do hourly work, btw 🙂

    Reply
  13. Got any advice for people using the Thisis theme by DIY Themes?

    I have created the side bars but can’t use them yet because I don’t know where to put the code you referenced for sidebar.php

    Reply
  14. Does this part go in your functions or sidebar file?

    if ( is_tree(‘main page title 1’) ) {
    if (!function_exists(‘dynamic_sidebar’) || !dynamic_sidebar( ‘sidebar1’) ) { $generic_sidebar = true; }
    }
    elseif ( is_tree(‘main page title 2’)) {
    if (!function_exists(‘dynamic_sidebar’) || !dynamic_sidebar( ‘sidebar2’) ) { $generic_sidebar = true; }
    }
    elseif ( is_tree(‘main page title 3’ )) {
    if (!function_exists(‘dynamic_sidebar’) || !dynamic_sidebar( ‘sidebar3’) ) { $generic_sidebar = true; }
    }

    I have this line of code in my sidebar file, do I get rid of it?:

    Also, I have different sidebars I want to show on different Pages. Where do I specify the Page name for each sidebar?

    Thanks a ton.

    Reply
  15. Oops that line of code in my sidebar file was:

    /* WordPress Widget Support */ if (function_exists(‘dynamic_sidebar’) and dynamic_sidebar(1)) { } else {

    Reply
  16. I am trying to do this with the wpng-calendar.php file from WPNG Calendar Plugin to have multiple widgets but I can’t seem to get it working once I duplicate the “register” line. Any help?

    Reply
  17. This trick is awesome! I got it to work on all of my pages except for my blog page…any ideas?

    Reply
  18. Hello, thanks for the tutorial. I get my sidebars to show in the admin, but they don’t show on the pages. I’m new to wordpress so this may be a silly question… but does this method work with 2.8+?

    Reply
  19. Might want to add an else statement to the end of the code in the sidebar.php, so there is a default state, so you don’t have to program a custom sidebar for each and every page. This worked for me:

    else {
    if(!function_exists(‘dynamic_sidebar’) || !dynamic_sidebar() ) { $generic_sidebar = true; }
    }

    – ryan

    Reply
  20. The issue of getting different sidebars to appear on different pages is one that I have been looking for a solution to. Thanks!

    Reply
  21. Hey Eric, this is a great post first off. I wrote something similar, but this is much more versatile with the multiple instances of widgets, and coding, etc.

    Anyways, I’ve gotten it to work nicely on a client’s site, but it does not seem to work when using a sub-sub page. The grandchild pages so-to-speak. Any idea why?

    Reply
  22. Is it possible to get a have a custom navigationbar depending on what page you are? Using wp-concept

    Reply
  23. Great post. I have to do something very similar to use different widgetized sidebars on the different sections of my site. As my understanding of WP and PHP grows, I’ve streamlined the code a bit but I wish there were a plugin to do this so I didn’t have such a big chunk of code on my page.php (I only use special sidebars on my pages).

    Reply
  24. There is a new wordpress plugin that allows to have multiple sidebars without writting any code, it’s called Custom Sidebars, and in few clicks you can create, widgetize, and set sidebars up.

    http://wordpress.org/extend/plugins/custom-sidebars/

    Cheers!

    Reply
  25. so i just added the code into my theme.php and now my entire site wont work..when you click on the link to visit the page its just white

    Reply
  26. Reply
  27. Hi Eric

    Thanks for mentioning the Delicious Cached++ plugin. I have recently refactored, and it now allows multiple widgets in a native (and more natural way). The “Delicious Cached++” widget appears only once, and you can add it multiple times (with independent settings – e.g., show bookmarks from different tags in each widget).

    Let me know if you have more curiosity on how to allow multiple widgets in a WordPress plugin!

    Reply

One Trackback

  1. By Gina Trapani on September 24, 2009 at 9:53 am

Post a Comment

I promise not to publish your email address.

*
*