How to add field for new site-wide option on Network Settings screen?

I’m working on a plugin, and part of it involves setting an option value that applies to all sites in a WordPress network. I know about the add_site_option and get_site_option functions that let you save the value into the wp_sitemeta table, but what I can’t figure out is how to place the fields in the appropriate place in the WordPress backend, and how to intercept the saving of sitewide values in order to insert the add_site_option call when that happens.

For the first problem (adding the fields), I would normally use the Settings API, specifically register_setting and add_settings_field, to whitelist the new option and then insert a field for it into the appropriate options page. But I can’t find information anywhere on whether you can use add_settings_field to add a field to the Settings page in the new Network Admin section of the backend, if there’s an alternative function that does what it does for Network Admin pages, or if you just have to inject the HTML manually. (You can do it manually by writing a function that echoes out the field and then connecting that function to the “wpmu_options” action, which gets run at the end of the Settings page in Network Admin. But then you also have to deal with nonces and everything else manually.)

Read More

The second problem probably involves finding an action that runs when the user hits “Save” on the Network Admin Settings page, but I’ve been unable to find that yet. Any leads would be greatly appreciated.

So — thoughts? Is there an elegant way to allow management of sitewide options for a plugin through the new Network Admin area? If so, how’s it done?

Related posts

Leave a Reply

3 comments

  1. There’s a wpmu_options action that lets you append more HTML on the Network Settings page.

    If you want to add your own sub-menu/page to the Settings parent menu:

    add_action('network_admin_menu', 'add_my_netw_settings_page');
    function add_my_netw_settings_page() {
      add_submenu_page(
           'settings.php',
           'Co za asy',
           'Co za asy',
           'manage_network_options',
           'my-netw-settings',
           'your_form'
      );    
    }
    
    function your_form(){
      $options = get_site_option('your_plugin');
    
      ?>
      <form action="<?php echo admin_url('admin-post.php?action=update_my_settings'); ?>" method="post">
        <?php wp_nonce_field('your_plugin_nonce'); ?>
    
        ...fields go here...
    
      </form>
      <?php
    }
    

    the save handler:

    add_action('admin_post_update_my_settings',  'update_my_settings');
    function update_my_settings(){     
      check_admin_referer('your_plugin_nonce');
      if(!current_user_can('manage_network_options')) wp_die('FU');
    
      // process your fields from $_POST here and update_site_option
    
      wp_redirect(admin_url('network/settings.php?page=my-netw-settings'));
      exit;  
    }
    

    Keep the save handler if you choose to use that action I mentioned above, and hook the form to that action.

  2. Basically, if you do not want to create your own network admin settings page, you will need to use both hooks mentioned separately in the other two answers:

    add_filter( 'wpmu_options' , 'show_network_settings' );
    add_action( 'update_wpmu_options', 'save_network_settings' );
    
    function save_network_settings() {
      // checkbox example
      if( isset( $_POST['my_network_checkbox'] ) )
        update_site_option( 'my_network_checkbox', '1' );
    
      // textfield example
      if( isset( $_POST['my_network_textfield'] ) )
        update_site_option( 'my_network_textfield', sanitize_text_field($_POST['my_network_textfield']) );
    }
    
    function show_network_settings() {
        $checkbox = get_site_option('my_checkbox'); 
        $text = get_site_option('my_text'); 
        ?>
        <h3><?php _e('My Network Settings','my-plugin'); ?></h3>
        <table class="form-table">
            <tbody>
                <tr>
                    <th scope="row"><?php _e('My Checkbox','my-plugin'); ?></th>
                    <td>
                        <label>
                            <input type='checkbox' name='my_checkbox' value='1' <?php checked( $checkbox, '1' ); ?> /> 
                        <?php _e('Check my box.','my-plugin'); ?>
                        </label>
                    </td>
                </tr>
                <tr>
                    <th scope="row"><label for="my_text"><?php _e('My Text','my-plugin'); ?></label></th>
                    <td>
                            <input type='text' name='my_text' value='<?php echo $text; ?>' />
                    </td>
                </tr>
            </tbody>
        </table>
        <?php
    }
    

    For a very clear explanation and useful code sample see http://zao.is/2013/07/adding-settings-to-network-settings-for-wordpress-multisite/

  3. I’m afraid that the only method I know of is the method you mentioned of manually inject the html and deal with the updates of the options yourself. The action you need to use for saving your options is update_wpmu_options. If needed I can provide a more detailed example, just let me know.