Custom Class per Widget on WordPress | Web Development Services by Ed Nailor

Adding Custom CSS Classes to WordPress Widgets

Print Friendly

I have worked on a number of designs that call for different styles being applied to sidebar areas. For example, let’s say the color pallet for a website includes a red, white and blue Americana design. The designer may have decided that the sidebar should have blue widget areas and red widget areas.

Traditionally, you have had to either know the widget id and add a specific class to that, or even just leave the colors all the same. But what if the design calls for the ability to add a red one in between the blue ones, and that it could be any type of widget? If you know ahead of time what that widget will be, you can add a class to your css to target, for example .text-widget-12 would hit the widget with this class assigned by WordPress. But what do you do if you don’t know what the client may want to add and when they may want to make that color red instead of blue?

Enter this great script!

Add the following code to your functions.php file and you will get the option to add custom css classes to your widgets. Add some predetermined classes to your css and the user can pick and choose which they want to do!

Custom CSS Classes for WordPress Widgets

Place code AFTER you have registered your sidebars.

[code]

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

[/code]

Option 1

Add Predetermined Classes for the User to Choose from:

[code]

/* Set your predetermied class choices here */
$myarray = "class1,class2,class3";

$myclasses = explode(",",$myarray);
$row = "<p>\n";
$row .= "\t<label for='widget-{$widget->id_base}-{$widget->number}-classes'>Class:</label>\n";
$row .= "\t<select name='widget-{$widget->id_base}[{$widget->number}][classes]' id='widget-{$widget->id_base}-{$widget->number}-classes' class='widefat'>\n";
foreach($myclasses as $myclass) {
$instance_selected = null; if($instance['classes']==$myclass) $instance_selected = " selected='selected'";
$row .= "\t<option value='".$myclass."'".$instance_selected.">".$myclass."</option>\n";
}
$row .= "</select>\n";

[/code]

Option 2

Allow the user to assign their own classes:

[code]

/* Allows User to Add Custom CSS Classes */
$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";

[/code]

Finalize Code

Now, close the code out from here:

[code]

echo $row;
return $instance;
}
add_filter('widget_form_callback', 'kc_widget_form_extend', 10, 2);function kc_widget_update( $instance, $new_instance ) {
$instance['classes'] = $new_instance['classes'];
return $instance;
}
add_filter( 'widget_update_callback', 'kc_widget_update', 10, 2 );
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' );

[/code]

Credit: This is a modified version of the code found at http://kucrut.org/2010/11/add-custom-classes-to-any-widget/. The modification was to allow the programmer to pre-populate the css classes the designer added to the design.



16 Responses to “ “Adding Custom CSS Classes to WordPress Widgets”

  1. kucrut says:

    That’s a great idea to prevent messy/invalid class names. Although I’ve incorporated the functions with my widgets plugin and added a class name validation your idea is just more simple and practical in most cases.

    Oh, you could also simplify your code to use WP’s builtin selected() function :)

  2. Ed Nailor says:

    I think I may have to look into adding that function.
    Luckily, the way it is done now has minimal impact on the code, but I do like the idea of something cleaner!
    Thanks
    Ed

  3. Ed Nailor says:

    Have noticed that the Widget Logic plugin interferes with this function. Looking to see what I can find. If anyone else finds a workaround, please let us know.

  4. CIDIC says:

    I can’t figure out how to get this to work with plugin widgets. Any Ideas?

  5. HallMarc says:

    I, like many of us, have been scratching my now bald head trying to find a solution that will allow Widget Logic to play nicely with ANY plug in that adds Custom Class/ID to Widgets. I tried asking Andy (ZigWidgetClass) and got impatient waiting for a response (yes, he answered within a decent amount of time <12 hours, being a coder and impatient anyway I dove in looking to find the problem). He and I both discovered that the issue is caused by the fact that WL needs to rewrite the callback array in order to function in the way that it does and in doing so keeps any other custom widget class plugin from visibly working.
    No biggie, just need to test to see if Widget Logic is active then if it is use the callback_wl_redirect instead of callback.
    Since Andy's fix was shorter and cleaner than mine I will show you his solution and all thanks should go to him:
    This is from his plugin; ZigWidgetClass
    This:

    $option_name = get_option($widget['callback'][0]->option_name);

    Gets replaced with this:

    if (!($widgetlogicfix = $widget['callback'][0]->option_name)) $widgetlogicfix = $widget['callback_wl_redirect'][0]->option_name; # because the Widget Logic plugin changes this structure - how selfish of it!

    $option_name = get_option($widgetlogicfix);

  6. Ed Nailor says:

    Thank you for the information. I will try this and see if it works.

    Honestly, since I was having trouble with this, I have moved to a different way of managing sidebars and getting away from using Widget Logic. My solution:

    I have a framework for WordPress I have developed (with most of the general items I usually include) that now supports the option of allowing up to 20 sidebars. I simply choose how many I want, name them as needed and then on each page/post have a drop down as to which sidebar I want to include. Each sidebar is specifically setup as needed. For example, if I knew I had a 10 page website, I could add 10 sidebars and name each after the page it would be added to. Then I could add the widgets as desired for each page. It may be a little more work on my end, but it seemed easier for the end user (normally my end client) to grasp rather than needing to understand the conditionals that Widget Logic requires. This prevented constant calls/emails asking how to allow a widget on one page vs another.

    The other way this could be used was to set a couple sidebars… say a generic one, a “tall” one (for pages with longer content), a blog one (with recent posts, tags, etc) and whatever else I may want to provide. Then the user simply chooses the sidebar they want to include.

    This is a more simplistic approach when the design allows for a single sidebar, but a lot of my clients prefer that anyway as they use the websites as more of a real website and not a blog. Its easy enough to override the sidebar setup if I need to go back to the standard WP way so it works for me.

    I just wish WordPress would provide an interface on the Page editor to address that page’s sidebar(s) directly (and the menu directly) as it seems to make more sense to be able to edit all aspects of a page/post while on that page, especially when WordPress is used more as a CMS than a blog setup.

    Anyway, thank you for this information. I will test this when I get some free time and let you know what I find on my end.

    Ed

  7. Ed Nailor says:

    @CIDIC:

    Did you ever get this figured out? I did not see your comment until today.
    Ed

  8. HallMarc says:

    @Ed: I just used this solution on KC Widget Enhancements because it also allows custom IDs as well as custom Class’ and it works here as well.

  9. Ed Nailor says:

    Very cool. Did you send the information to the authors of these plugins? Would be great if they implemented these so we don’t have to use modified plugins when updates are provided.
    Ed

  10. bristweb says:

    i am also having the widget logic issue. additionally, i’ve noticed that the class drop down does not show on all widgets.

    i tried looking up these functions on the codex but cannot find the filters?

    widget logic with theme defined classes really seems to be the ideal solution because it allows the template designer to give the administrators options without hardcoding particular styles. tons of widget positions also seems like a poor alternative…

  11. Awesome, this totally works! Thanks!

  12. David says:

    So I had the same problem that others did with Widget Logic and this very useful bit of code. The code that Hall Marc posted was correct except that the variables are different from the other code posted here so it took a little sorting out. Here is my completely code that does work with Widget Logic: http://pastebin.com/7DkRJCjN

    (This also has a little bonus feature I added which capitalizes the class names and removes the underscore for a nice effect on the user end.)

    Thanks for the helpful post.

  13. Ryan Dennler says:

    PERFECT! This is exactly what I was needing to overwrite some styling that being generated by the theme conflicting with an Ad plugin I was using to generate campaigns for me.

    THANKS!

  14. pingvincible says:

    Great article, great code! Just what i was looking for!

  15. Dapper says:

    Thanks, for this.

  16. Excellent!
    I am a huge fan of building functions into my themes rather than relying on plugins. This is a great addition. Now I just need to dive into it to figure out how I can apply it only to specific widget areas of my choosing.

    Thanks again for this great headstart!

Leave a Reply

Your comments are welcomed and invited, but please note that comments are moderated due to spam.
Spam comments will be marked as such and sumbitted to AKISMET for processing throughout the entire
WordPress world. Don't spam here... It won't get through!