WordPress + Multisite: How to add custom blog options to Add New Site form in Network Admin

Wordpress

In a WordPress Multisite installation I'm customizing, I need to add a simple text field to the entry form for creating new blog sites, which is located at

Network Admin > Sites > Add New

Naturally I need this field to get saved along with the other meta data from that form, in the {new_blog_prefix}_options table.

I'm particularly interested for the simplest, most straightforward, and/or the "right way" (i.e. The WordPress Way) to accomplish this, but I'll settle for The Way That Works™!

So far I've encountered numerous dead-ends in my research:

  • Settings API – [WP Codex]

    As far as I can tell, the Settings API (a) may not work for the Network Admin section (although this may have changed in a recent version of WP); furthermore, (b) it seems like this only lets you add/modify screens in the Settings section of the Dashboard.

  • wpmu_options hook – [Hooks DB]

    Seems to be a hook exclusively for adding options to the Network Settings screen.

  • add_site_option / add_blog_option – [WP Codex]

    Closest I can find; seems to allow adding site-specific options to the {blogsite_prefix}_options table, but still doesn't help with adding options to the Admin form.

So… no dice. Any help is appreciated!

Best Answer

If you look at the source code of the 'Add New Site' page, you can see that WordPress does not provide a hook for this purpose. Of course, it would be possible to add a hook yourself, but it is generally bad practice to edit the WordPress core.

However, once submitted and all information is present, the page calls the function wpmu_create_blog(). In this function there is a hook called, namely the action wpmu_new_blog:

do_action( 'wpmu_new_blog', $blog_id, $user_id, $domain, $path, $site_id, $meta );

At this point the blog is already created. However, we can still detect if a field was submitted by hooking onto this action and saving it into the database. We add the following into our plugin file (or template):

function add_new_blog_field($blog_id, $user_id, $domain, $path, $site_id, $meta) {

    // Make sure the user can perform this action and the request came from the correct page.

    switch_to_blog($blog_id);

    // Use a default value here if the field was not submitted.
    $new_field_value = 'default';

    if ( !empty($_POST['blog']['new_field']) )
        $new_field_value = $_POST['blog']['new_field'];

    // save option into the database
    update_option( 'new_field', $new_field_value);

    restore_current_blog();
}

add_action( 'wpmu_new_blog', 'add_new_blog_field' );

As for displaying the field onto the page, you could use a JavaScript approach. You add a javascript file, solely to the 'Add New Site' page, and onLoad of the page you insert the field into the correct position on the page. You should add an input field with the name 'blog[new_field]'. We create the following JavaScript file which, once loaded, adds a new field to the 'Add New Site' page:

(function($) {
    $(document).ready(function() {
        $('<tr class="form-field form-required"></tr>').append(
            $('<th scope="row">New field</th>')
        ).append(
            $('<td></td>').append(
                $('<input class="regular-text" type="text" title="New Field" name="blog[new_field]">')
            ).append(
                $('<p>Explanation about your new field</p>')
            )
        ).insertAfter('#wpbody-content table tr:eq(2)');
    });
})(jQuery);

Now the only thing left to do is include this file onto the 'Add New Site' page, by adding this to your plugin file:

// Only add the script for the page site-new.php (the page hook).
add_action( "admin_print_scripts-site-new.php", 'my_admin_scripts' );

function my_admin_scripts() {
    wp_register_script('yourScript', plugins_url('js/yourScript.js', __FILE__));
    wp_enqueue_script('yourScript');
}

Further suggestion could be, depending on your needs: Add an input field in your general settings page using add_settings_field, such that a user can edit it later (and maybe only if it is the default setting for this field). A 'you cannot change this field later' approach.

I hope this is the help you needed.

Related Topic