Sidebars in WordPress
Over the past few months, I’ve seen the code for hundreds of WordPress themes. I’ve seen some beautiful code and some downright nasty code. One thing that I’ve seen more often than not is the same few lines for handling sidebars. This is code from 2007 and most likely copy-pasted from older WordPress themes.
I just wanted to clue an extremely large portion of the theme development community in on a little secret: sidebars have been a part of WordPress core and have seen some updates over the last three years.
With that in mind, I’m going to walk you through the steps of creating and using sidebars for WordPress themes. Maybe you’ll even pick up on some things you didn’t know about. The goal is to teach theme developers how to properly register sidebars and end this cycle of using outdated code.
What are sidebars?
The term “sidebar” actually refers to two different things in WordPress:
- Dynamic sidebar: A container for a set of widgets, which the user can set from the Widgets screen in the admin.
- Sidebar template: A theme template that displays content.
In most situations, a theme would register a dynamic sidebar and load its widgets within a sidebar template. This isn’t always the case, but it’s generally what you’ll see. It’s important to understand that there’s a difference though.
Generally, the term “sidebar” refers to a dynamic sidebar, which is the focus of this article. However, I will touch on sidebar templates as well.
One thing I’ve been disappointed with when looking at themes is that many theme developers aren’t fully taking advantage of one of the most powerful features of WordPress. Most themes will only have a single sidebar, maybe two at most. But, these themes will create large theme options pages for things that could be easily handled with widgets or put content directly in templates. I’d love to start seeing themes with more sidebars.
Registering a dynamic sidebar
Themes usually fail my quality guidelines the most in this area, so if you’re a theme developer, let’s make sure you get this right. Properly registering a sidebar is the most important part of the process because what you set here will trickle down to other sidebar functions you’ll use later.
When registering a sidebar or multiple sidebars, you would do so from your theme’s
functions.php
file.
The code shown below is an example of how to properly register a sidebar in WordPress using the register_sidebar() function. In this particular example, you’ll register a sidebar called
primary
, which will be the example sidebar used throughout the remainder of this tutorial.<?php
add_action( 'widgets_init', 'my_register_sidebars' );
function my_register_sidebars() {
/* Register the 'primary' sidebar. */
register_sidebar(
array(
'id' => 'primary',
'name' => __( 'Primary' ),
'description' => __( 'A short description of the sidebar.' ),
'before_widget' => '<div id="%1$s" class="widget %2$s">',
'after_widget' => '</div>',
'before_title' => '<h3 class="widget-title">',
'after_title' => '</h3>'
)
);
/* Repeat register_sidebar() code for additional sidebars. */
}
?>
It’s fairly simple stuff for most theme developers, yet so many themes have a mess when you look at their sidebar registration code.
Arguments for dynamic_sidebar()
The
register_sidebar()
function accepts a single parameter named $args
, which is an array of arguments that define how the sidebar and its widgets should be handled. In the example above, each of these arguments were manually set.id
The
id
argument is perhaps the most important argument you can set (see the “Bad sidebar code” section below on why you definitely need to set this). WordPress will use the ID to assign widgets to a specific sidebar, and you’ll use the ID to later load the sidebar.
Each ID should be unique to the sidebar. By default, WordPress sets this to
sidebar-$i
(where $i
is a count of the registered sidebars).'id' => 'primary',
name
The
name
argument is the human-readable label for your sidebar used in the WordPress admin. You can set this to anything you think best represents the name of your sidebar. Generally, sidebars are given a name that lets the user know where it’ll appear in the theme.
This argument can also be internationalized. So, make sure you set a proper textdomain when preparing your theme for translation. The default for this argument is
Sidebar $i
(where $i
is a count of the registered sidebars).'name' => __( 'Primary' ),
description
The
description
argument was introduced in WordPress 2.9. It allows you to set a specific description for how the sidebar is used within your theme. This argument defaults to an empty string. It can also be internationalized.'description' => __( 'A short description of the sidebar.' ),
before_widget
The
before_widget
argument is a wrapper element for widgets assigned to the sidebar. It should also be a block-level HTML element. This argument has a couple of things that you should always set with specific code so that plugins can properly use them, which is the id
(%1$s
) and class
(%2$s
) attributes.
By default, WordPress sets this as a list item:
<li id="%1$s" class="widget %2$s">
. I’m not a big fan of making sidebar widgets list items. I typically always go with a <div>
.'before_widget' => '<div id="%1$s" class="widget %2$s">',
after_widget
The
after_widget
argument is pretty simple. It’s used as the closing wrapper for widgets assigned to the sidebar. You just need to close off the element you set for the before_widget
argument. By default, WordPress sets this to </li>
.'after_widget' => '</div>',
before_title
Most widgets display a title if the user sets one. The
before_title
argument is the opening wrapper element for the sidebar’s widget titles.
By default, WordPress sets this to
<h2 class="widgettitle">
. I don’t like using an<h2>
in this scenario. An <h3>
or <h4>
seems more semantic. I’m also not sure about the non-hyphenated class name, which makes it nearly unreadable.'before_title' => '<h3 class="widget-title">',
after_title
The
after_title
argument is to close the wrapper element set in the before_title
argument. By default, WordPress will set this to </h2>
. You just need to make sure you set it to properly match the value you gave to the before_title
argument.'after_title' => '</h3>'
Displaying a dynamic sidebar
Once you’ve registered a dynamic sidebar, you’ll want to display it within your theme. WordPress has a function for this called dynamic_sidebar().
The
dynamic_sidebar()
function takes a single parameter of $index
, which can either be the sidebar’s id
or name
argument (set when you registered the sidebar). While you can technically use either, it’s almost always safer to use the id
you set.
Using the below code in one of your theme templates, you can display the
primary
sidebar, which we registered in the previous section. Note that I also used a wrapper element so the sidebar can be easily styled.<div id="sidebar-primary" class="sidebar">
<?php dynamic_sidebar( 'primary' ); ?>
</div>
Generally, this code would go within a file called
sidebar-primary.php
, which you’ll learn about in the “Sidebar templates” section later. However, dynamic_sidebar()
can technically be called anywhere within your theme.Displaying default sidebar content
Some themes developers may opt to display default content when a user hasn’t assigned any widgets to a specific sidebar. To check if a dynamic sidebar has any widgets, you would use the is_active_sidebar() conditional tag.
Like the
dynamic_sidebar()
function used to load the sidebar, is_active_sidebar()
accepts a single parameter of $index
, which should be the ID of the sidebar you want to check for active widgets.
With the below code, you can check if the
primary
sidebar has widgets. If so, display the widgets. Else, display some custom content.<div id="sidebar-primary" class="sidebar">
<?php if ( is_active_sidebar( 'primary' ) ) : ?>
<?php dynamic_sidebar( 'primary' ); ?>
<?php else : ?>
<!-- Create some custom HTML or call the_widget(). It's up to you. -->
<?php endif; ?>
</div>
Collapse sidebars without widgets
The previous example showed you how to display default content when a specific sidebar is inactive. But, you also have the option of completely collapsing (not showing any content) if the sidebar is inactive.
Again, you’ll use the
is_active_sidebar()
function to check if the primary
sidebar has any widgets assigned to it.<?php if ( is_active_sidebar( 'primary' ) ) : ?>
<div id="sidebar-primary" class="sidebar">
<?php dynamic_sidebar( 'primary' ); ?>
</div>
<?php endif; ?>
Sidebar templates
We’ve covered everything you need to know about using dynamic sidebars. Actually, there’s some other interesting functions if you feel like digging around the core WordPress code. For now, let’s take a look at sidebar templates.
Sidebar templates are typically used to house the code for a dynamic sidebar (see “Displaying a dynamic sidebar” above). The average WordPress theme has a single sidebar template called
sidebar.php
. If your theme has a single sidebar, this is all you’ll ever need.
Sidebar templates are loaded within a theme using the get_sidebar() function. The code below is what you would use to load a
sidebar.php
template:<?php get_sidebar(); ?>
The
get_sidebar()
also accepts a single parameter of $name
, which allows you to load a more-specific sidebar template. For example, the code below would call thesidebar-primary.php
template.<?php get_sidebar( 'primary' ); ?>
For the best organization of your theme and separation of code, you would create a specific sidebar template for each of your dynamic sidebars. Suppose you created two dynamic sidebars with the IDs of
primary
and secondary
. To best organize these, create both a sidebar-primary.php
and sidebar-secondary.php
template for handling those sidebars.
You would use the code below to load both of these sidebar templates:
<?php get_sidebar( 'primary' ); ?>
<?php get_sidebar( 'secondary' ); ?>
The above is just the convention I use for sidebar templates. You can mix this up a bit to do things in a way that best suits you. The most important thing to do is make sure you use the
get_sidebar()
function when loading a sidebar template.Bad sidebar code
There are some common things I would like to see changed within themes. Not all of these things are technically incorrect, but they can present some unintended consequences or are just needless bits of code.
Problem #1: Randomly dropping code into functions.php
If you’re a theme developer, you should be familiar with WordPress’ built-in hooks. Not only should you be familiar with them, you should actually be using them.
The biggest issue I see is sidebar code just being dropped into
functions.php
. You should create a sidebar registration function and hook it to widgets_init
. You can see an example of this in the “Registering a dynamic sidebar” section above.
The reason this is important is so that child themes (and even plugins) can know exactly when a sidebar was registered. This gives child themes the opportunity unregister a sidebar if needed. Plus, not doing it this way is just plain sloppy.
Problem #2: Not setting sidebar IDs
Many people don’t realize this but when you don’t explicitly set a sidebar ID, you’re asking for trouble. When you use
register_sidebar()
orregister_sidebars()
without setting individual sidebar IDs, WordPress auto-creates these IDs by counting the number of registered sidebars and assigning a number as the ID.
This sounds great in theory. However, there’s a huge problem. When a plugin or child theme comes along and registers a new sidebar, this new sidebar gets the ID of 1 (if registered earlier in the flow), which alters the IDs of all the other sidebars. From an end user’s point of view, all of their widgets get assigned to a different sidebar.
Utter chaos.
Widgets are assigned to dynamic sidebars according to the sidebar ID. If that ID changes, the widgets appear to shift to a different sidebar. That’s why it’s important to manually set the sidebar IDs when registering a sidebar. Properly setting the ID is shown in the “Registering a dynamic sidebar” section above.
Another benefit of manually setting the ID is that you know exactly what the ID is for use in other functions such as
dynamic_sidebar()
and is_active_sidebar()
.Problem #3: Backwards-compatiblity checks
The PHP
function_exists()
check is not needed. I’ve seen this in at least 80% of themes that I’ve looked at. As mentioned earlier in this post, dynamic sidebars have been around since 2007. The only reason to use this to check for sidebar functions is for backwards compability. However, most themes aren’t actually backwards compatible. And, backwards compatibility isn’t something I’d recommend beyond one version back.
One common check is to see if the
register_sidebar()
function is present as shown below. Forget about this check and simply register the sidebar.if ( function_exists( 'register_sidebar' ) )
The same goes for a check of
dynamic_sidebar()
. Rather than checking if this function exists, simply call the sidebar.if ( function_exists( 'dynamic_sidebar' ) )
Problem #4: Not using get_sidebar()
When loading a sidebar template, I often see this code (or something similar):
include( TEMPLATEPATH . '/sidebar.php' );
This is not the proper way to load a sidebar template. WordPress has a function called
get_sidebar()
for handling this. Always use it as shown in the “Sidebar templates” section above. The reason you should use this function is because a specific hook (get_sidebar
) is executed when this template is loaded, which plugins might use to handle specific features.
There are cases where
get_sidebar()
might not be appropriate for a specialized theme, but it’s something I’ve rarely seen.Let’s update those sidebars
I’ve been reviewing some of the themes submitted to the WordPress themes repository over the last few months and figuring out how the theme review process works. I’ve literally looked at the code of 100s of themes in this time. Nearly every theme I’ve seen has at least one of the issues I described in the “Bad sidebar code” section of this article.
The goal is to help new and veteran theme developers create better-coded themes. This is only a single issue of many, many common issues I’m seeing in themes. I’ll probably write more on other issues in the future, but for the moment, I hope this article will help theme developers clean up their sidebar code.
Refer:
http://justintadlock.com/archives/2010/11/08/sidebars-in-wordpress
0 comments:
Post a Comment