I have been working a lot lately on customizing my personal homepage theme. One thing I have not been happy about has been the right sidebar. The widget heading were just html text and didn’t have the rendered look that I wanted. I decided to reformat the sidebar and use images for the headings rather than just text. I had done some custom sidebars before but I wasn’t sure how to style each widget independently. The problem is that WP gives a generic class to each sidebar widget and you are only able to style all of them to look the same.
The first place I looked for a function to do this was in my template’s function.php file and I noticed this code:
if ( function_exists('register_sidebar') )
register_sidebar(array(
'before_widget' => '<div class="sidebar-box">',
'after_widget' => '</div></div>',
'before_title' => '<h2><span>',
'after_title' => '</span></h2><div class="sidebar-box-inside">',
));
This isn’t exacly what I wanted as it will apply this to all of my widgets. So after a little more snooping around the web I noticed a WP filter that does what I want. The fitler is called dynamic_sidebar_params and it is called like this:
add_filter('dynamic_sidebar_params', 'my_function_callback');
Where my_function_callback is the name of your function. In my case I called it like this, in functions.php:
add_filter('dynamic_sidebar_params', 'sidebar_styling');
Next I had to figure out a way to style each element uniquely. I decided that the widget name would be a good identifier. Luckily this filter will pass you a field called widget_id, which has a sanitized version of the name which can be used for your CSS identifier. Here is what the params variable looks like:
Array
(
[name] => Sidebar 1
[id] => sidebar-1
[before_widget] => <div class="sidebar-box">
[after_widget] => </div></div>
[before_title] => <h2><span>
[after_title] => </span></h2><div class="sidebar-box-inside">
[widget_id] => recent-posts
[widget_name] => Recent Posts
)
Now that we have that ID, it is a simple function to write:
function sidebar_styling($params){
$params[0]['before_title'] = '<h2 id="sidebar-'.@$params[0]['widget_id'].'"><span>';
return $params;
}
Now WP will output the unique id for each heading and we can just style it appropriately. I used a big sprite to save resources:
#sidebar-recent-posts span{display: none;}
#sidebar-recent-posts{
background: transparent url(images/sidebar-titles/dynamic-sidebar.png) 0 0 no-repeat !important;
}
#sidebar-twitter-tools span{display: none;}
#sidebar-twitter-tools{
background: transparent url(images/sidebar-titles/dynamic-sidebar.png) 0 -41px no-repeat !important;
}
#sidebar-categories span{display: none;}
#sidebar-categories{
background: transparent url(images/sidebar-titles/dynamic-sidebar.png) 0 -82px no-repeat !important;
}
#sidebar-archives span{display: none;}
#sidebar-archives{
background: transparent url(images/sidebar-titles/dynamic-sidebar.png) 0 -123px no-repeat !important;
}
#sidebar-links span{display: none;}
#sidebar-links{
background: transparent url(images/sidebar-titles/dynamic-sidebar.png) 0 -164px no-repeat !important;
}
That is all there is, you can see the results on the page you are reading.
I found these articles/sites helpful:
Related posts:
nice work, see you are delving deep into customizing wordpress.
Nice work – the finished effect is very cool.
I think there’s an easier way you could have achieved this though – if you have a look in the source code of wp-includes/widgets.php, the default code used (for registering a sidebar) looks like this:
array(
‘name’ => sprintf(__(’Sidebar %d’), $i ),
‘id’ => “sidebar-$i”,
‘before_widget’ => ”,
‘after_widget’ => “\n”,
‘before_title’ => ”,
‘after_title’ => “\n”,
);
I’ve never taken the time to figure out why it works, but if you use the classes and IDs they use, you should get the same effect – the widget name as a class/id on the elements.
Blast – I forgot that the commenting template would remove the tags… let me see if I can try that again:
array(
‘name’ => sprintf(__(’Sidebar %d’), $i ),
‘id’ => “sidebar-$i”,
‘before_widget’ => ‘<li id=”%1$s” class=”widget %2$s”>’,
‘after_widget’ => “</li>\n”,
‘before_title’ => ‘<h2 class=”widgettitle”>’,
‘after_title’ => “</h2>\n”,
);
True, the default settings will work, however this technique is if you would like to override the default settings of workpress. Wordpress by default will use list elements for widgets, if you notice in my site I use divs. So this technique applies only to if you want to have this effect while overriding the default “register_sidebar” function. So I am pretty sure if you want total customization of your widgets and sidebar formatting, you need to use this technique.
Yea thats true!
[...] Styling individual widgets within sidebar [...]
Great work – thanks!
I think that this ‘comment’ is SPAM…
JF
Adrian thanks for publishing this. I was just about to give up on using customized sidebar heads on a client’s site.
Hi, i was still confused about where to place/call the customized function sidebar_styling for actual usage.
Also, how do the function knows which css paired with the corresponding widget? (since the dynamic sidebar may not generate the widgets in order.
tks ^^ you did a great job and helps lots of wp fans!
Hi,
I am not a php expert, but I added all of this code to the right files and can’t seem to get it to work. I didn’t do anything with the params variable, do I need to add it somewhere?
Thanks!
This is what worked for me following the above explanation:
My function.php page:
——————————————-
”,
‘after_widget’ => ‘‘,
‘before_title’ => ”,
‘after_title’ => ”,
));
add_filter(’dynamic_sidebar_params’, ’sidebar_styling’);
function sidebar_styling($params1){
$params1[0]['before_title'] = ”;
return $params1;
}
?>
——————————————-
Simple as that. The only additional coding is CSS.
Great. PHP code didn’t paste right there. Maybe the mod can fix it.
I was just making a point that he only needs to change his function.php page in case it wasn’t clear.
Thanks again for the solution.
Hi,
Great tip.
I’m almost there, but I’m having trouble uniquely naming each widget title. They get IDs but are structured like: #sidebar-twitter-2
I get lost with the params variable.
Where is it supposed to go?
Any idea about how to move the titles outside of the sidebarbox div?
i need an h3 then a div to add some jquery magic.
I’m still struggling with this…
are there any alternatives?
For some reason a number is being added to the end of each id. e.g. “text-widget-3″
Help would be really appreciated!
Dan
Thanks a lot. This idea helped me with my styling stuff for the wordpress widgets
Josh
how would you add markup to just one widget? say for example you want a link to the tagcloud widget to a full tag page?
this doesn’t seem to work correctly for me. I can get it to display different bgs for each widget, but when I specify span { display: none; } it doesn’t show the h2 tag at all. If I take that line out, the text displays over my nice pretty header image
I solved this by removing the span { display: none; } line and adding text-indent: -9999px to the h2 attributes.
Hi, I know I am bit late for the discussion but I would love some help with this. I can’t get the id’s to appear to the code. As i can’t post php here if anyone could email me to help that would be really great. Thanks, Hannah
[...] that is created from a script. It was quite difficult in finding this little known function, but Adrian Mummey has written a great article on it and shown how to use [...]