WordPress Bits

Hacking WordPress. Keeping the bits together.

Cleaning up after the WordPress widget party

Posted by Leonid Mamchenkov on August 11, 2007

In one of the recent posts – “Advanced Widgets. Widgets with controls.” – we saw how to create WordPress widgets, which could have configuration options.  In one of the comments to that post, Matthew Smith, asked a very good question:

do the widgets leave settings in the database upon removal? Should these be cleaned up using a hook like unregister_widget() (if it exists, I haven’t looked yet)? Or does WordPress do this automatically?

Nicely spotted, Matthew!  Thank you.

Indeed, what happens there?

Widget settings are stored in regular WordPress options.  Some widgets can be re-used several times (like Text widget and  RSS widget).  This can cause plenty of data to be flowing around.  That, in turn, can affect web site’s performance and server’s memory usage.

What can we do about it?   It’s obvious that we have to do some sort of clean-up routine, but how, when and where?

To answer those questions, let’s refresh our memory with how we got ourselves into that mess in the first place.  WordPress options are updated and populate from within our widget control.  Here is the control code that we used for that article:

Control for advanced date widget

Here we see the call to update_option(), which populates the database with our stuff.   This routine is registered as widget control, using the following line (again, the code is from the previous article):

Register sidebar widget with control

Here is a call to register_widget_control() function.  This is how we add stuff.  So, to remove stuff, there should be something like unregister_widget_control() somewhere.  Let’s look through WordPress code for a bit… ah, here it is, found it!  wp-includes/widgets.php (no link to WordPress Source this time, as it features version 2.1-alpha2, which didn’t have widgets yet, so use your own copy of WordPress for reference)has definitions of all widget things that we saw registering – unregister_sidebar(), unregister_sidebar_widget(), and unregister_widget_control() .

OK, now that we know that it would be nice to call unregister_widget_control() and delete_option() for our widget, where is the best place to do so?  I mean, if we just add those calls to our widget file, it will get unregistered and we won’t be able to use it.  How can we know when is our widget in use and when it’s not and when is it the best time to do the cleanup?

The answer to that, of course, depends a lot on how you do things.  There are many places to create widgets (themes, plugins), so there is no single recipe here.   But from the first glance, it seems, that putting all widget stuff into a  plugin makes sense.  When the plugin is activated, both the widget and its control are registered, and the database option is populated.  When the plugin is deactivated, the widget and the control are unregistered and the database option cleaned up.

We’ll look at how to create widget plugins in one of the upcoming posts.  (There are still a few issues in that area that I need to figure out before I can do a full blown post on that.)

14 Responses to “Cleaning up after the WordPress widget party”

  1. zedlander said

    This isn’t just widget specific:
    Any wordpress plugin will leave it’s options in the database, even when deactivated, unless it specifically removes them like you talk about above. The problem is, I often deactivate a plugin which I am still planning on using later. For example, looking for which plugin is causing trouble, or even just upgrading WordPress. If the options were removed, then I would lose all my customized settings. So, I think this is actually more of a feature than a bug.

  2. Zedlander,

    yes, you are right.

    But this post is more for the developers, who might want to decide to clean up the mess after themselves. For example, an RSS widget (not the one included in WP, but a third-party one) could store recently fetched/parsed items in the option. With multiple instances of such a widget, this could get huge pretty easy. And in case you re-enable such a widget/plugin, fetching and parsing te data once again won’t add much.

  3. […] Cleaning up after the WordPress widget party In one of the recent posts – “Advanced Widgets. Widgets with controls.” – we saw how to create WordPress […] […]

  4. […] Cleaning up after the WordPress widget party In one of the recent posts – “Advanced Widgets. Widgets with controls.” – we saw how to create WordPress […] […]

  5. @zedlander when leo showed me the wordpress options trick to show all the available options I saw a number of options which were not supposed to be there since they belonged to some old plugins that I had tried out before. Kind makes me wonder is there a way to clean up my wordpress database. also does this effect my wordpress DB in anyway. I guess the best option would be a complete reinstall :(

  6. Arpit Jacob,

    you can cleanup your options table using any SQL administration tool (PHPMyAdmin, for example). Make sure to saave the table as it is before you do any changes, so that you can restore and try again, if something goes wrong. ;)

  7. Trevor said

    (I am Zedlander, btw)
    I think this tool is the best solution:
    http://www.mittineague.com/dev/co.php
    A user can then choose to remove options from plugins which they no longer need.

  8. Trevor/Zedlander,

    Thanks for the link. Yeah, the tool looks like the best shot possible without WordPress actually registering plugin options.

    Here are a couple of scenarios that would be almost impossible to catch with a plugin like this:

    Scenario 1 (option name is a constant):


    define(OPTION_NAME,'my_ugly_option');
    add_option(OPTION_NAME, 'test value', 'test description');

    Scenario 2 (option name is a dynamically built variable):


    $option_name_prefix = 'my_ugly_';
    $option_name_test = 'test';
    $full_option_name = $option_name_prefix . $option_name_test;
    add_option($full_option_name,'test','test description);

    However, the plugin might still be useful for catching most of the stuff out there. I see the examples are all about RSS feeds saved in the options table – it makes a lot of sense to clear those out, as they tend to grow easily.

  9. Thanks for the reply!

    Because I am currently focusing on theme design (and haven’t moved to plugins or more in-depth core tinkering), I wonder if there is a way to hook the function that changes themes (once again, I don’t have time to look right now). If so, when your theme is deactivated you could have a “cleanup” function that removes all preferences related to your widgets and theme (for more advanced themes).

    Another interesting point was brought up on the performance side of things; I need to do a more indepth study of the performance effect of widgets, plugins, and other files. For instance, is it faster to place all your widget code in a single file (functions.php) or is it faster to uses include() statements to pull in the the widgets (because of overhead involved in opening files, etc)?

    I have really enjoyed your articles and they definitely make it a bit easier to jump into wp hacking (especially since I have more knowledge of C and java than php and mysql).

  10. Matthew,

    Yes, there is a way to do things on theme switch. The way it works is like this (from wp-admin/themes.php file):

    1. User clicks on activation of new theme in the admin interface.
    2. Option ‘template’ is updated with the new value (if set in the URL)
    3. Option ‘stylesheet’ is updated with the new value (if set in the URL)
    4. Action ‘switch_theme’ is called with parameter of current theme (retun value of get_current_theme() function which is defined in wp-includes/theme.php).

    So you can hook to ‘switch_theme’ action and check if the name of the supplied theme is NOT the same as your theme, then do the clean-up stuff.

    Performance issue is a whole topic on its own. There are many variables. Even the question that you mention depends on the way you have things set up. Opening and reading one file is faster than many files. But many files can be conditioned and open/read only when needed. And stuff like that…

    I hope we’ll touch WordPress optimization in some of the upcoming posts, even though I haven’t done much of it myself (but there is a guy now interested to do guest blogging on WordPress Bits about this subject).

  11. Awesome! I’m glad to hear about that, because I’d love to optimize my site as much as possible. As for the widget cleanup, I’ll implement something and let you know – I just finished up and installed my new theme on my site, so I need to add the cleanup ability in order to create a neat, self-contained theme+widgets+options (no theme options yet, but I’m sure I’ll add them later) that behaves nicely. As for performance, not only am I curious about the file open/close issue, but I am interested in the effect that plugins have on site performance. I am sure that less = better, but I wonder how many is too many.

  12. Matthew,

    only you can decide how many is too many. If your site does everything you want it to do, if the response times are OK with you, if it doesn’t fry the hardware every other weekend, if your bandwidth consumption is within your budgets, if … you get the idea. :)

    P.S.: good job with the theme there

  13. […] regular expression match all the possible variations in syntax? As Leonid Mamchenkov posted on the WordPress Bits blog , the plugin will not find occurrences of options where the option name is a constant or a […]

  14. […] https://wpbits.wordpress.com/2007/08/11/cleaning-up-after-the-wordpress-widget-party/ […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: