Add Custom Class(es) to ANY Widget

WordPress has a powerful API for creating, configuring and displaying widgets, but one thing I really need is the ability to add custom class(es) to the widgets. Every widget should usually come with its own classname, which will be printed when the sidebar is being displayed. So, assuming you’ve used the correct method for registering sidebar, you can add these following functions to your theme/plugin to provide the user the ability to add custom class(es) to the widgets.

Update #2
I’m retiring KC Widget Enhancements and have written an new plugin that only provides this functionality. For now, you can get it from GitHub. Please note that you will need to re-enter you widget attributes, because the attibutes are saved with different keys.

Update
I’ve created a plugin for this so you won’t need to edit your theme/plugin files anymore 🙂 Download it from WordPress plugins repo.

There are three steps involved:

  1. Adding an input field on the widget configuration form
  2. Updating the widget options
  3. Adding our custom class(es) to the widget markup

Adding an input field on the widget configuration form

function kc_widget_form_extend( $instance, $widget ) {
	if ( !isset($instance['classes']) )
		$instance['classes'] = null;

	$row = "<p>n";
	$row .= "t<label for='widget-{$widget->id_base}-{$widget->number}-classes'>Additional Classes <small>(separate with spaces)</small></label>n";
	$row .= "t<input type='text' name='widget-{$widget->id_base}[{$widget->number}][classes]' id='widget-{$widget->id_base}-{$widget->number}-classes' class='widefat' value='{$instance['classes']}'/>n";
	$row .= "</p>n";

	echo $row;
	return $instance;
}
add_filter('widget_form_callback', 'kc_widget_form_extend', 10, 2);

The kc_widget_form_extend() simply adds a new input field on the widget configuration form. You can add another field here if you’re feeling adventurous 🙂

Updating the widget options

function kc_widget_update( $instance, $new_instance ) {
	$instance['classes'] = $new_instance['classes'];
	return $instance;
}
add_filter( 'widget_update_callback', 'kc_widget_update', 10, 2 );

The kc_widget_update() functions added a new option to the widget which will be saved to the database when you hit the Save button.

Adding our custom class(es) to the widget markup

function kc_dynamic_sidebar_params( $params ) {
	global $wp_registered_widgets;
	$widget_id	= $params[0]['widget_id'];
	$widget_obj	= $wp_registered_widgets[$widget_id];
	$widget_opt	= get_option($widget_obj['callback'][0]->option_name);
	$widget_num	= $widget_obj['params'][0]['number'];

	if ( isset($widget_opt[$widget_num]['classes']) && !empty($widget_opt[$widget_num]['classes']) )
		$params[0]['before_widget'] = preg_replace( '/class="/', "class="{$widget_opt[$widget_num]['classes']} ", $params[0]['before_widget'], 1 );

	return $params;
}
add_filter( 'dynamic_sidebar_params', 'kc_dynamic_sidebar_params' );

The last step is to modify the widget’s markup. When you call the dynamic_sidebar() function, WordPress prepares the markup for every widget, including its id and classes. It took me a while to figure out a way to modify the markup and I’m not really sure that it’s the best one, but it sure does the job 🙂

First, we pull all registered widgets from the global $wp_registered_widgets variable. Since we don’t want to modify all widgets, we need to filter the one we want using the $params variable that WordPress passed to our function. When we found the widget, we’ll check if it has custom class(es) added, and then add them to its markup.

Now you can use those custom classes in your stylesheet to give your widgets some unique look n’ feel 🙂