I was trying to install Robert Plank's Action PopUp plugin on a WordPress MU blog today. The plugin would activate, but when I tried to update any of its settings, I would get an error message:

Error! Options page not found.

At first I wondered if the plugin was not compatible with the 2.7 version of WordPress, but it seemed to work fine on one of my vanilla WordPress 2.7 installations. Must be an MU problem. It turns out that the new Settings API in WordPress 2.7 owes partial thanks to WordPress MU development. Whereas use of the API is still optional in plain WordPress, MU requires plugins to get on board and scrap the old way of storing settings.

The WordPress Codex has the official story. I'll give you my version...

First, if you don't have one already, you'll need to create a function and add it as a WordPress admin_init action. It'll look something like this:

function myplugin_admin_init() {
	register_setting('myplugin-options', 'myplugin-option1');
	register_setting('myplugin-options', 'myplugin-option2');

add_action('admin_init', 'myplugin_admin_init');

Currently, it seems that the only documentation for these functions is in the wp-admin/includes/plugin.php source file.

Basically, register_setting takes three arguments. The first an option group name, so a unique identifier for the all the options for your plugin. The second argument is the name for a single option—it should be unique to avoid conflicts with other plugins. Every option on your plugin settings page needs one.

The third argument is optional; you can specify the name of a callback function (as a string) to sanitize user input before it is stored in the database.

Once you've registered all of your options, you can build your admin settings form like this:

The important thing is that the settings_fields() function appear inside the settings form. As the WordPress Codex explains:

settings_fields() outputs all of the hidden fields that options.php will check, including the nonce. You no longer need to setup the page_options hidden field if you use the new API.

Then, just make sure that the name attribute of your form inputs matches the option name you registered with WordPress.

Thanks to Casey Bisson for his help with this.