Widget-ready WordPress sidebars without headlines

A lot of people are asking me (of course I have to make this stuff up because I don’t have any readers) how I’ve done the menu bar (the horizontal thing containing static pages and categories, just below the name of this blog). This is a good question, because the menu bar is actually widget-ready, so I don’t have to change it when I add new categories. “But how have you avoided the widget headers and still remained strictly XHTML compliant?”, I hear some of my imaginary readers say. Well, I’ll tell you how.

First step is to understand how WordPress sidebars are done:

  1. Theme tells that it has sidebar(s) using either register_sidebars(n) or one to several calls to register_sidebar(...). This is done in functions.php.
  2. Where the sidebar should appear, you call dynamic_sidebar(), and if it returns false, you render some static stuff instead of widgets.

All this is explained in excruciating detail in WordPress documentation, so look it up in there, if you want to know exactly how it’s done. Now when all this is done, your call to dynamic_sidebar() (done inside <ul> and </ul> tags) will output the widgets selected to this sidebar in the following manner:

<li id="..." class="..."><h2 class="widgettitle">Pages</h2>
<ul>
<li><a href="...">Page 1</a></li>
<li><a href="...">Page 2</a></li>
</ul>
</li><li id="..." class="..."><h2 class="widgettitle">AnotherWidget</h2>
<ul>
<li><a href="...">Link 1</a></li>
<li><a href="...">Link 2</a></li>
</ul>
</li>

Now any Google-aware reader will already know, that horizontal menus can be made from unordered lists using the following CSS definitions:

#menu ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

#menu li {
  float: left;
}

Now because the ul element doesn’t have margins or borders, and li elements float after each other, we could even have several unordered lists after each other, and still the result would look like one horizontal menu. Now the problem is how to get rid of the Widget names completely. Well, this can be done quite easily. If you look up the register_sidebar() function call from the Widgets API, you see that you can actually have an array of parameters governing the way widgets and their titles are outputted to the sidebar.

By setting before_widget and after_widget to empty strings, and not having <ul> and </ul> around
your call to dynamic_sidebar(), and setting before_title and after_title to beginning and end of a comment block, we achieve everything needed. So in your functions.php, you would have the following code (notice how I have named the sidebar “Topmenu” to make it easier to recognize that particular sidebar in WordPress widget configuration):

register_sidebar(array('name' => 'Topmenu',
		'before_widget' => '', 'after_widget' => '',
		'before_title' => '<!--', 'after_title' => '-->'));

Which would reduce the widget code shown above to something like this:

<!-- Pages -->
<ul>
<li><a href="...">Page 1</a></li>
<li><a href="...">Page 2</a></li>
</ul>
<!-- AnotherWidget -->
<ul>
<li><a href="...">Link 1</a></li>
<li><a href="...">Link 2</a></li>
</ul>

Now only thing you need to do is to put your menu-generating piece of code where you want it, in my case it was the header.php of my theme:

<?php /* Widgetized sidebar, if you have the plugin installed. */
if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Topmenu') ) : ?>
<ul>
<li><a href="http://www.somesite.com">Static menu item 1</a></li>
<li><a href="http://myblog.com">Static menu item 2</a></li>
</ul>
<?php endif; ?>

Now all you need is to go into WordPress site admin, and select Presentation > Widgets, and add the relevant widgets to your brand-new Topmenu (I use the Pages and Categories widgets). And you’re done!

Please leave comments if you have any questions or further suggestions.

Published by

Joonas Pihlajamaa

Coding since 1990 in Basic, C/C++, Perl, Java, PHP, Ruby and Python, to name a few. Also interested in math, movies, anime, and the occasional slashdot now and then. Oh, and I also have a real life, but lets not talk about it!

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.