WordPress Bits

Hacking WordPress. Keeping the bits together.

Automating WordPress customizations – the install.php way

Posted by Leonid Mamchenkov on August 10, 2007

In “Automating WordPress customizations – the plugin way” we looked at how to change a whole bunch of thing in one go by having our own plugin.  The plugin approach can save a lot of time, but it does not actually give any control over the installation process.

Often we want to interfere with the way things are.  For example, upon successful WordPress installation you find a web site with one post (“Hello World!”), one page (“About”), and a test comment to the first post.  Also, there is a category “Uncategorized”, and “admin” user, and a few other things in the database, which are not so obvious (for example, user roles, such as Administrator, Editor, and Subscriber).

There are also a few things, which are happening during the installation process itself.  For example, a random password for the administrator is generation, and email is sent to the administrator’s address with credentials and new site details.  As handy as it is for a friend’s new blog, there are many situations when we don’t want this done, or want it done differently.

WordPress has a way to control installation flow via a custom install.php file, which saves you from all the problems of core files editing.  In this post, we’ll see how to use this feature and what can actually be done with it.

Let’s start with some source diving.  Before we do any modifications of our own, it’s good to get an idea of how things work under the hood.   The installation process starts with wp-admin/install.php , so this where we’ll start too.  This is what we see at the top of the file (chopped off on the right a bit, but it doesn’t matter for now):

Top of install.php file

A flag that signals that we are in the installation process is set, and a check is done for the presence of the wp-config.php file, which should have database credentials, table prefix, and things like that.  So far so good.

Then the content of wp-config.php is imported.  OK, makes sense.

Then the content of upgrade-functions.php is imported.  Hold on. What’s that?  Let’s see the content of that file before we go forward.  Maybe there is something interesting in there.  Here are the first few lines:

Top of upgrade-functions.php file

A check is done for the presence of wp-content/install.php file.  And if it exists, it’s included straight away.  But what is in this wp-content/install.php file?  I don’t have any in my brand new and shiny WordPress installation.  Did I do something wrong?

No!  This is exactly what we were looking for.  This is the way WordPress gives you all the power over the installation process.  Before it does anything itself, it checks if instructed it to do anything.  If you don’t have your own wp-content/install.php file, WordPress will do its own installation routine.

What can we do with it now?  Anything.  But anything is too broad of a thing.  We need a test of our new superpowers.  How about we cancel a WordPress installation altogether?  That should prove how much power we have over WordPress.  So, here is the content of the first version of my wp-content/install.php file:

Custom install.php version 1

Looks sufficient.  Now let’s see what happens to the installation process… Oh, Noooo! It didn’t work!  It worked, but it didn’t do everything I wanted it to.  Here is how my WordPress installation screen looks now.

Broken WordPress installation v1

My evil signature appears at the top of the installation screen, but the installation didn’t stop.  Why? Because, actually I never told it to.  So, here is the second version of my custom install.php, which should fix the problem:

Custom install.php version 2

Now I tell WordPress to exit (as in finish, stop, end) from the installation process, like everything is done.  And it works!  Here is how my installation screen looks now:

Broken WordPress installation v2

So, now there is no way to install WordPress.  I have full control over the matter.  And that makes me feel all that powerful and important. Now that we established the authority (“Respect my authorita!” © South Park), how can we do good?

Although you can completely re-write and re-implement WordPress installation process, it’s not something you’d want to do very often.  After all, it works, right?  So, why break it?  What we do want often though is some minor changes to the process.

How can we achieve this?  Is there a simple way of modifying WordPress installation without creating it from scratch ourselves?  The answer is – yes.

Let’s look further down into the wp-admin/upgrade-functions.php file.  It has functions, alright.  But there are a few places where it checks for the presence of the function, before defining it.  See the example of wp_install().

Middle of the upgrade-functions.php file

Notice that function_exists(‘wp_install’) check?  Why is it there?  Doesn’t WordPress know which functions it has and which it doesn’t?

This is the nice way that WordPress gives us to control the installation process without much work on our side.  If we look through the file, we’d notice that there are four functions which are defined in this way:

  • wp_install()
  • wp_install_defaults()
  • wp_new_blog_notification()
  • wp_upgrade()

So, these are the places where we can easily interfere.

Since we only want to change just a few things, we can start from the existing code.  We can achieve that by simply copying the code from WordPress definitions of these functions into our custom install.php and change a few lines there.  If we have any of those functions defined in our install.php, WordPress will use those instead of its own ones.

IMPORTANT: if we are to supply WordPress with our own functions, than we should accept the parameters and return values as WordPress expects them.  Otherwise, things might break.

So, what do those special functions do?


This function handles the installation routines.  It calls other methods, which create database tables, populate options with default values, create user roles, etc.  It also creates an admin user with a random password and assigns it an Administrator  role.  Once everything is done, it calls another function to send a notification about successful blog installation.


This function creates all those default entries that you find in your new WordPress installation – first post, first comment, first page, default category, and a bunch of links in the blogroll.


This function generates and sends that email with username and password which site administrator gets upon a successful installation.


This function handles the upgrade process.  If you made a lot of changes to the installation process, chances are you’ll want to make sure those changse are handled properly during the upgrade of the system, and so this is the function to help you out in that.

Here are a couple of examples of what you might want to do.

Modify user roles

If you want your web sites roles to be configured differently, you can, of course, use an excellent Role Manager plugin and set them just the way you want.  But that would be a pain to do over and over again for new sites.  So, it might be a better option to customize things automatically during the installation process.

Here is how to do that:

  1. See how populate_roles() function works (it is defined in wp-admin/upgrade-schema.php file)
  2. Define your own function (say populate_my_roles()) in your custom install.php
  3. Copy the definition of wp_install() function from wp-admin/upgrade-functions.php into your custom install.php
  4. Add a call to your role functions (populate_my_roles()) after the call to populate_roles() in the copied wp_install() function.

Add, change or remove default category, post, page, links

I’ve heard many people who want to start with “General” category, not “Uncategorized”.  And if you are making lots of WordPress-based web sites, than first post, page, and comment probably don’t make much sense – you remove them right after the installation.  If you are WordPress installations for corporate clients, you often want to lose the default links (as much as you love WordPress developers, links to their blogs don’t make much sense from your clients’ web sites).

wp_install_defaults() is the place to do all that.   Copy it to your custom install.php .  If you want to start with a clean WordPress installation – remove all lines in that function.  Just delete them.  So that you have only the function definition and nothing else.  Otherwise, add and edit the lines accordingly.  Most of the stuff you see in WordPress’ function definition are SQL statements anyway.  So you can put your own ones here.

Now it is time to return to the wp-admin/install.php file, which we got carried away from by all those upgrade functions.  If you scroll through really slow, you’d notice that there is something about steps in there.

Installation steps

These steps are used to move the user from one installation screen to another.  In the same file, there is a switch() statement, which selects the appropriate screen to show.  There are a few links and forms in the file, that specify to which step the installation should switch further.  Those a bit difficult to spot because of all the HTML markup in the file, but you can search for “step” and see where it is used.

The install.php file from WordPress can be used as a real example for a custom installation routine.   If you want to change the way your WordPress is installed, what the user is asked, or which functions are called at which points of the installation, install.php is a valuable reference.

Did I miss anything?

31 Responses to “Automating WordPress customizations – the install.php way”

  1. Hey Leonid.. these are some great tricks.. thanks for it.. i am definitely going to try all this tonight..

  2. Karthik,

    cool! Let me know how it goes. Maybe we can do another post later to follow-up the issues that you discover on the way.

  3. huh dude where the hell are you finding all this stuff I haven’t ever seen it on the CODEX. The more I read your blog the more I am beginning to love WP.

  4. hehe… it’s all there, in the source ;)

  5. Jonathan said

    I was just about to ask the same thing. I wish I had known about all of this two years ago. :o\

  6. Very, very cool. Comes in very handy when managing multiple blogs on a site.

    I’ll definitely use this with my multiblog system!

  7. Stephen,

    you might want to take a look at:

    1. WordPress MU – it’s a version of WordPress which supports multiple blogs. It’s the same software that WordPress.com runs, and code-wise it’s almost the same as regular WordPress.

    2. “Host multiple WP sites on one installation” – yet another way.

  8. Jonathan,

    well, I guess it’s better late than never. ;)

  9. […] Automating WordPress customizations – the install.php way In “Automating WordPress customizations – the plugin way” we looked at how to change a whole bunch of thing […] […]

  10. […] Automating WordPress customizations – the install.php way In “Automating WordPress customizations – the plugin way” we looked at how to change a whole bunch of thing […] […]

  11. Leonid — I’m familiar with MU. That second link is an interesting variation on my method. Seems a bit hazard-prone, though, as any domain at all could point to it and affect the database…. Fixable I’m sure, but not fixed yet. :)

  12. Stephen Rider,

    I guess the fix would be very much dependent on each particular setup. Actually, even the recipe itself would too. I guess, right now it’s more of a “show me the way” kind of thing, rather than the final solution…

  13. You’ve inspired me to rummage around the source code a bit more. There are all kinds of fun things you can customize in similar ways.

    I just discovered that you can put a /languages/ folder in wp-content, and thus avoid having to remember to transfer files every time you upgrade WordPress. (note sure why this isn’t just the standard locaiton…) Some other interesting things in here to. :)

  14. Stephen Rider,

    glad to hear about your inspiration ;)

    The post about languages is in plans. One of the non-obvious uses for translations is customization of strings. It’s like doing an English-to-English translation from WordPress-speak to your own dialect.

  15. zone said

    I tend to install the same plugins on each of my several blogs. Is there a way to automate the installation of a default set of plugins whenever you install wordpress?

  16. twincascos said

    I’ve just been going through this tutorial and it seams to be out of date already. WP 2.8 has either moved or changed file names and or functions.

  17. Jeremy said

    Very interesting article, I will certainly come back to it later, I always wanted to create my own custom installation.

    By the way, you were talking about wp_install_defaults(). Would there be a way to add content to my wordpress install by calling an XML import file with posts, categories, … in wp_install_defaults()? That would be really helpful to be able to do that.

  18. The wp-admin/install.php file has changed in recent versions, but a wp-contents/install.php file will still be included as the article described.

  19. John said


    Your post is interesting. What I want is that how my wordpress will be customized when it once installed all the plugins I want is too running, and a lot of pages.

  20. I wish someone would update these instructions. I really want to try this, but I have not been able to figure it out with current WordPress.

  21. M said

    Here’s something I learned about writing how-to articles over the past 14 years, as I wrote over 3000 articles that were published by a major computer magazine:

    Never ask questions in your article. The point of a how-to article is to ANSWER questions. Asking questions within the body of the article is annoying and condescending, and reflects poorly on the author.

    Best wishes.

  22. I agree with Jessi, would be great if you updated these instructions for WP 3.0

  23. Hello!
    I was wondering if all of these tips mentioned have changed since WordPress 3.1 has come out? If not, please let me know. If so…what can I do to make the changes in WP 3.1.

    Thanks in advance. I finally found what I was looking for. Hopefully you can do the same in the newer versions of WP.

  24. flash said

    @leonid —

    this is great // in regards to @jessi’s comment — i’ve been working thru this w/ 3.0.1 && was thinking about writing up something about how to create a custom install // would love potentially collaborate.


  25. […] Automating WordPress customizations – the install.php way […]

  26. […] erste Weg ist in unter dem Link https://wpbits.wordpress.com/2007/08/10/automating-wordpress-customizations-the-installphp-way/ beschrieben. In einem der Kommentare ist aber auch ein Link auf den zweiten Weg […]

  27. […] came across a super interesting post at WPBits about automating the wordpress installation process.  Some of the parts about how where some of the functions are located in WP that allow you […]

  28. tomexsans said

    I would like to try this out, But i think its outdated, following would be futile. But this is the only site i read about this. All in all nice. .

  29. […] I am wondering whether there is an updated version of the methods described in the post below for customising the WordPress install. https://wpbits.wordpress.com/2007/08/10/automating-wordpress-customizations-the-installphp-way/ […]

  30. […] Professional, cheap & fast PHP, CGI/Perl script installation & secure file transfer services, with fast delivery of services within 24 hours & at affordable prices. Read More… […]

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s

%d bloggers like this: