WordPress Bits

Hacking WordPress. Keeping the bits together.

Automating WordPress customizations – the plugin way

Posted by Leonid Mamchenkov on August 9, 2007

If you installed WordPress more than two times, you know the drill. Download the latest version, unzip or untar, copy config-sample.php into config.php, edit config.php, upload files to your web host, visit new WordPress URL, click “Next Step” a couple of times, while submitting blog name and administrator’s email. After all is done, login with username “admin” and provided random password, go to Options menu, and set things the way you want them to be. Then upload and activate chosen plugins, and then switch theme to something you’ve spent some time searching for or designing.

Overall, the process is very simple and straight forward. And there are rumors that it will be even simpler in upcoming versions of WordPress. It’s all nice and good. But there is something that only you can make better.

If you installed WordPress more than two times, and by now we know you did, chances are you have a certain way of configuring things. You probably use the same administrator’s email. Or want to use a pre-defined password, not a randomly generated one, because you seriously can’t remember random passwords for those 20 test WordPress installations just on your laptop. Now, going through Options, setting things the same every time is boring.

There are, of course, better ways. In this post we’ll see how to automate this task with a plugin. In one of the near future posts we’ll see how to do even better with a custom install.php file.

To get a few ideas for a starting point, let’s look at what WordPress does itself. It uses some defaults for sure, as there are many things that we don’t need to change when we login for the first time. Yes, those are called reasonable defaults, and WordPress has them specified somewhere. Let’s look.

I’ll save you some source code digging and tell you where the yummy stuff is. SQL scheme and default options are in wp-admin/upgrade-scheme.php file, and some initial records, like first post, first page, first comment, and default blogroll are done from wp-admin/upgrade-functions.php .

So, now that we know what WordPress sets for it’s defaults, we have an idea of what we want to change. Let’s pick something simple, just for the sake of the example. Say, I want to use 20 items in RSS by default, not 10. And I want to disable smilies, because most of my WordPress installations are for corporate clients with very little sense of humor. The options I am therefor interested in are ‘posts_per_rss‘ and ‘use_smilies‘. I want to set 20 for the first one, and 0 for the second one.

It’s time to write my plugin. Here is the first version, as small and simple as I cared to make it:

Local settings plugin version 1

I save this code into local_settings.php file and upload it to wp-content/plugins/ folder. Now I can see a new plugin entry in the Plugins management.

Before I activate my plugin, I want to see the old values. I check the Options->Reading screen and see that Syndicated Feeds -> Show the most entries is set to 10, as in all WordPress installations by default. I also make a test post with a smily in it and check that the smily image in fact appears on my new WordPress front page. And just to be absolutely sure, I look through all options quickly for the values that I’m interested in. Everything is right – default WordPress stuff.

Now I Activate my plugin and rush back to Options->Reading to see the changes. Hooray! The number of items in my RSS feed is set to 20 now. Reload the front page, and I don’t see the smily anymore. It’s pure ASCII stuff – columns and brackets. Quick list of options confirmed that the default WordPress values are now in fact my default values.

A quick beer to celebrate the victory and and a new skill in my toolbox. But wait.. what’s that? Hold on! Oh, no! It seems that I can’t change my default values to anything else now…

I do want to have my own defaults, yes. But I want to be able to change them on those sites that need changes. Like with WordPress values – I can change all the defaults I want. Now, whenever I change the number of RSS items in Options->Reading screen and save a new value, it seems to have no effect. My default of 20 items comes back no matter what I do.

The good thing is that I just started my celebrations, and my mind is still sober. I am quickly enlightened to the fact that those two lines in my plugin are executed on every WordPress page load. I specified no conditions at all.

It’s time for the second version of my plugin. This time, I want those lines to execute only once, when my plugin is activated. How do I tell WordPress to execute those lines at specific moment in time? I need a hook. A quick look at Plugin API and WordPress Hooks sorts me out. It turns out, I am looking for register_activation_hook() function. So, here is the second version of my plugin:

Local settings plugin version 2

What’s happening here? Nothing much. I put all my options in a function. And then I told WordPress to call this function every time a plugin in the current file is activated.

A test is in order. I go to my Plugins management and disable the old version. Now I go to Options->Reading and change my default value back to WordPress default value of 10. Save it and make sure that it works. It does (because my super plugin is disabled and does not interfere with the balance of nature). Now I upload the new version of my plugin, go back to Plugins screen and Activate it. A quick check with Options->Reading confirms that the value of RSS feeds was set to my default of 20. And I can change it now too. The smily test is also passed and I’m smiling too over a new bottle of beer.

While I enjoy my pint, I have a couple of small ideas on how to improve my plugin. First of all, I want to set default WordPress values back when my plugin is deactivated. This seems like a proper line of behavior. So, here is the third version of my plugin, which adds this important functionality:

Local settings plugin version 3

For any action there is a reaction. For any activation there is a deactivation. I don’t even have to dig through the documentation anymore. I’m assuming some things exist, and they in fact do. This is one of the reasons I love WordPress so much.

Another round of tests shows that everything works OK. I’m proud enough to show this little thing to one of my co-workers, who immediately spots the problem. You see, this is why you should stick to open source code as much as possible, and show your code to as many people as possible. It’s just so much easier to make your code better this way.

The problem my co-worker noticed is with going back to WordPress defaults. It is true, WordPress sets those values that I use as initial defaults. But those values aren’t necessarily the same when my plugin is activated. So, instead of going back to initial WordPress values, I should return to values which were set before my plugin was activated. To do so, I have to save those values before I overwrite them.

Here comes the fourth version (and final for now) of my plugin:

Local settings plugin version 4

Whoa! It’s a long one! But I’m just building on the previous versions here. I get the values of the options before I overwrite them with mine. I save them into two other options (‘orig_posts_per_rss‘ and ‘orig_use_smilies‘). When my plugin is deactivated, I revert the changes. And, being a good WordPress citizen that I am, I delete the unused options.

While testing the plugin, the quick access to WordPress options tip comes handy. When my plugin is activated, I can see the extra options in the list of all options, although there is no direct user interface to edit those options. When my plugin is deactivated, I can make sure that the unused options are deleted.

Saved original option values

Here, you have it. A quick and easy way to customize WordPress installations without doing lots of boring manual work and without modifying any internals. Next time we’ll see a totally different approach to this problem – a customized install.php file. If you are in a hurry, you can find all about it yourself. I gave you all the hints already.

35 Responses to “Automating WordPress customizations – the plugin way”

  1. Jeremy said

    Leonid, it’s probably better to use <pre>’s inside <blockquotes> instead of screenshots, so people can copy-and-paste your examples.

  2. hey thats a very useful tip… i am definately going to be using this in the future..

  3. Karthik,

    glad that you liked it. Be sure to come back for the install.php recipe then. Maybe it’ll suit your needs better. Unless, of course, you know all about it. :)

  4. Kristin said

    I think this could be very useful for people running MU sites, as if there’s anyone around hacking core files is the MU admins.

    Anyway, I’ll try this out and see what happens.

  5. Kristin,

    Maybe… I find it helpful for standalone WordPress customizations. I have quite a few sites of my own, as well as for clients of the company that I work for.

  6. SEOdesign said

    Hi! Good post!
    I really like that you explain all the WordPress basics recently.

    A question: in version 4.0, shouldn’t the wp_defaults() function at line 2 (inside the get_option() part) say ‘orig_use_smilies’ and not ‘use_smilies’ ??

  7. SEOdesign,

    Good catch! A bug indeed. I updated the post with the new screenshot. Thanks.

  8. Tony said

    Thanks for the great hints about the install method! It is really nice to be able to change the default category names, and remove the default blogroll entries before they are created!

  9. vaughany said

    I think you just caused me to become interested in writing WP plugins! Well done.

    -Vaughany.

  10. Tony,

    you’re welcome. There’s more fun stuff to come. Stay tuned. :)

  11. Vaughany,

    Good! That was my ultimate target. :)

  12. Sadish said

    Thats a really useful plugin. can you also post a list of names for different options ?
    something like ‘posts_per_rss’ defines the “number of posts in RSS”

    how do we set the admin user’s password to be something we want?

  13. Sadish,

    check the quick access to WordPress options post. It’ll tell you how to see the Options in your current WordPress installation. For the list of WordPress defaults, check the source code of the wp-admin/upgrade-scheme.php . There are plenty of add_option() lines. Most of them makes sense if you read them carefully.

    For the rest, here are a list of place you could find help at.

  14. BobWms said

    Man! I like what you do and how you do it! Please keep up the good work and sharing ways. Thanks!!

  15. Aaron said

    This method can also by used to change the home and siteurl automatically for people who copy databases to a local install.

  16. Matt said

    I think a better way would be to filter the options on the fly, so defaults are never touched and you don’t have to worry about what happens when you revert the plugin. Every option has a unique filter, so try something like this:

    add_filter('pre_option_gzipcompression', create_function('$a', "return '0';"));

  17. […] Automating WordPress customizations – the plugin way If you installed WordPress more than two times, you know the drill. Download the latest version, unzip or untar, copy […] […]

  18. yeah sure, i am coming back..

  19. Aaron,

    care to elaborate? How do you see this done?

  20. Matt,

    Thanks for the tip! I’ll check it out.

  21. Dgold said

    This is really neat! I was just interested to look inside upgrade-functions.php and upgrade-scheme, and see what it’s doing.

    I agree with Sadish as far as: there are so many options in here, it would be cool future-content perhaps to tell some of the ones that are useful to change. Like your example of turning off smilies for corporate clients. What are some more good tricks with this?

    What’s the best way to remove the Category ‘Uncategorized’ and always start off with 3 categories, let’s say ‘News’ and ‘Sports’ and ‘Comics’? I saw the reference to the category in upgrade-functions and figured I could rename the first default category anything I want, but I wasn’t sure how to replace 1 with 3.

    thanks again for the interesting blogs about wordpress here

  22. Dgold,

    Your question should be answered by the next post – automated WordPress customizations with custom index.php file.

    But just not to keep you waiting, I’ll tell you another way. There is a wp_insert_category() function that does just that. It is defined in wp-admin/admin-db.php , in case you want to see.

  23. […] Posts Automating WordPress customizations – the plugin wayA look inside the WordPress databaseQuick access to WordPress optionsA look at WordPress filters. […]

  24. Jeremy,

    I tried that before, but it made the code much harder to understand (no indentation and no highlighting). Making it in colors and with spaces AND copy-paste-able is way too much work for me, and really stops me from posting as often as I can.

    So after a few different attempts, I decided to stick to screenshots, as they are the easiest to produce for me, and provide the best looking chunks of code for the readers here. I’m trying to make code samples as small as possible, so there shouldn’t be any problem re-typing them.

    If there is a better way some day, I’ll switch. But for now I could find anything acceptable.

    P.S.: Sorry for a delayed reply – Akismet triggered a false positive on your comment.

  25. Aaron said

    care to elaborate? How do you see this done?

    The easiest way is to just filter the home and siteurl options: (ignore the function names, I pulled them out of a project.)

    add_filter('option_home', 'sprcat_fix_link',0);
    add_filter('option_siteurl', 'sprcat_fix_link',0);

    function sprcat_fix_link ($link){
    $url = str_replace(array('www.','./'),'',$_SERVER['HTTP_HOST']);

    if(strpos($link,$url) === false ){

    $link = preg_replace('/(http.*?\:\/\/w*\.*)(.*?)(\/?.*)/','${1}'.$url.'${3}',$link);

    }
    return $link;
    }

    You could get all fancy and actually change the link, but this will be perfect if you have a mirror install. If you don’t you may have to use an if/else instead of the preg_replace:


    if($url != 'anthologyoi.com'){
    $link = 'http://localhost/test/dev/aoi/';

    }

  26. Aaron,

    it’s clear now. Thanks a lot for the explanation. Indeed, this is one way to do this, and suits well for development-production switching. In fact, this can be further extended with a couple of admin options, for URLs on production/development servers. This way a single version of plugin can be used to work on multiple sites – handy for web design companies, like ours.

    Thanks for the idea. :)

  27. […] Automating WordPress customizations – the plugin way – How to create a plugin to automatically set defaults in WordPress to your specifications. Really useful for anyone who manages multiple WordPress installations. […]

  28. […] Automating WordPress customizations – the plugin way If you installed WordPress more than two times, you know the drill. Download the latest version, unzip or untar, copy […] […]

  29. Murk said

    Idea for future article:

    Automated mirroring, i.e. d/load the sql dbase from the first server, install it on second server, rewrite references in the wp dbase to reflect the new location (e.g. server name and path – possibly blog title/subtitle).

    Repeat process automagically at intervals.

    (Yes, there is the feedwordpress plugin, but that doesn’t take all the data, e.g. comments etc)

  30. Murk,

    thanks for the suggestion. There are indeed quite a few plugins to handle this task, but perhaps it’s time to give them all a hard look and select the one that does the job properly. ;)

  31. […] cleanup is called and options are removed from the database.  We saw how to do this before, in the automation with plugin […]

  32. […] It seems I am becoming a customizing WordPress the plugin way […]

  33. vipin said

    thx for the info

  34. […] Automating WordPress customizations – the plugin way Hvis du implementerer nye WordPress-blogs, vil du som regel altid starte med at tilpasse alle indstillingerne, præcis som du vil have det. Her beskrives hvordan man laver et plugin, der hurtigt sætter alle éns standard-indstillinger. […]

  35. Outliver said

    i very much appreciate your style of writing :)

Leave a reply to Kristin Cancel reply