In this guide, we’ll introduce the WordPress Settings API, and create a WordPress administration page where we demonstrate the use of this API.
For the purposes of this tutorial, we’ll wrap this functionality into a plugin, but this can also be a part of a WordPress theme.
As the WordPress Codex says, the Settings API was added in WordPress 2.7 to streamline adding different settings fields and sections in administration pages.
Creating the Plugin
To start, we’ll create and activate a plugin to encapsulate our options page. We’ll use WP CLI to simplify the creation, although this leaves us with way more files than this guide needs.
Once it’s activated, we open the main plugin file — in this case smohub-settings-api.php
.
Creating the Admin Page
It isn’t necessary to use WP CLI for this plugin. We could have simply created a directory with the name of the plugin, and the PHP file inside it with the same name. Anyhow, the creation of the plugin has left us with a smohub-settings-api.php
which looks like this:
<?php
/**
* Plugin Name: Smohub Settings Api
* Plugin URI: PLUGIN SITE HERE
* Description: PLUGIN DESCRIPTION HERE
* Author: YOUR NAME HERE
* Author URI: YOUR SITE HERE
* Domain Path: /languages
* Version: 0.1.0
*
*/
~
Now we can simply add code after the comment end.
To add our options page, we’ll use add_options_page()
(more details about it here). This function takes arguments as follows:
add_options_page( $page_title, $menu_title, $capability,
$menu_slug, $function );
All the arguments are self-explanatory. $menu_slug
must be a unique string that WordPress will use internally, but will also be reflected in the URL. $function
is a string with a name of the function that will provide HTML output for our admin page.
We will, therefore, add the following code to our plugin file:
add_action( 'admin_menu', 'smohub_settings_page' );
function smohub_settings_page() {
add_options_page( 'Settings API Page', 'Settings API Page', 'manage_options', 'settings-api-page', 'settings_api_page' );
}
After we’ve saved the file (presuming we activated our plugin), we’ll open our administration dashboard, and we’ll find our Settings API Page under Settings in the left side menu.
We can control, to a degree, the order or position of the submenu item by adding a priority argument to our add_action()
function:
add_action( 'admin_menu', 'smohub_settings_page', 1 );
If we want to have our menu item to be in the root menu — rather than the Settingssubmenu — we’ll use add_menu_page()
, which takes similar arguments.
Now, if we open the page in our browser, all we’ll see is an empty page, because we still haven’t created the settings_api_page()
function that we specified:
The Settings API
The WordPress Settings API is an intricate mechanism that attempts to provide an easy way for developers to create settings pages.
Before we go into a full-fledged example of the settings page displaying and saving a setting to the WordPress database, we’ll explain couple of crucial functions that WordPress provides as part of its Settings API.
register_setting() is a function we use to register a setting, which equals a row in wp_options
table. Before we can create actual field (or fields, as setting can be an array of values), we need to register it. This way we’ll leverage the WordPress CRUD mechanism for settings. Function arguments are as follows:
register_setting( string $option_group, string $option_name, array $args = array() )
The first two arguments are mandatory, the first one allowing us to assign fields to it, and $option_name
, as we’ll see, is the actual option name in the WordPress database.
add_settings_section() defines/adds a section to an admin page. Its arguments are as follows:
add_settings_section( string $id, string $title, callable $callback, string $page )
$callback
is a function that outputs an HTL header of the section (it can be empty), and $page
is the slug of the admin page we’ll display it on.
add_settings_field() defines a settings field within a settings section in an admin options page. Arguments for it are:
add_settings_field( string $id, string $title, callable $callback, string $page, string $section = 'default', array $args = array()
Of these, $id
, $title
, $callback
and $page
are required. The $callback
function should output the HTML of the input field.
The Settings API provides $page
argument for add_settings_section
and add_settings_field
as a means to add sections and fields to existing settings pages. We’ll use smoPlugin
for both our option group — in register_setting()
— and for attaching the settings section and settings fields to a ‘smoPlugin’ page in the add_settings_section()
and add_settings_field()
functions. We’ll then “quote it” in the next two functions in our example, to output relevant HTML.
settings_fields() outputs “nonce, action, and option_page fields for a settings page”. It takes the $option_group
argument, used in register_setting()
.
do_settings_sections() outputs all the sections, with their respective fields, registered for a specific $page.
$page
is the only argument here.
Having explained these functions, we now proceed to some actual code. The previous PHP code we added to the smohub-settings-api.php
file we replace with the following:
add_action( 'admin_menu', 'smo_api_add_admin_menu' );
add_action( 'admin_init', 'smo_api_settings_init' );
function smo_api_add_admin_menu( ) {
add_options_page( 'Settings API Page', 'Settings API Page', 'manage_options', 'settings-api-page', 'smo_api_options_page' );
}
function smo_api_settings_init( ) {
register_setting( 'smoPlugin', 'smo_api_settings' );
add_settings_section(
'smo_api_stpPlugin_section',
__( 'Our Section Title', 'wordpress' ),
'smo_api_settings_section_callback',
'smoPlugin'
);
add_settings_field(
'smo_api_text_field_0',
__( 'Our Field 0 Title', 'wordpress' ),
'smo_api_text_field_0_render',
'smoPlugin',
'smo_api_stpPlugin_section'
);
add_settings_field(
'smo_api_select_field_1',
__( 'Our Field 1 Title', 'wordpress' ),
'smo_api_select_field_1_render',
'smoPlugin',
'smo_api_stpPlugin_section'
);
}
function smo_api_text_field_0_render( ) {
$options = get_option( 'smo_api_settings' );
?>
<input type='text' name='smo_api_settings[smo_api_text_field_0]' value='<?php echo $options['smo_api_text_field_0']; ?>'>
<?php
}
function smo_api_select_field_1_render( ) {
$options = get_option( 'smo_api_settings' );
?>
<select name='smo_api_settings[smo_api_select_field_1]'>
<option value='1' <?php selected( $options['smo_api_select_field_1'], 1 ); ?>>Option 1</option>
<option value='2' <?php selected( $options['smo_api_select_field_1'], 2 ); ?>>Option 2</option>
</select>
<?php
}
function smo_api_settings_section_callback( ) {
echo __( 'This Section Description', 'wordpress' );
}
function smo_api_options_page( ) {
?>
<form action='options.php' method='post'>
<h2>Sitepoint Settings API Admin Page</h2>
<?php
settings_fields( 'smoPlugin' );
do_settings_sections( 'smoPlugin' );
submit_button();
?>
</form>
<?php
}
Here we hook the smo_api_settings_init()
function to the admin_init
hook. There we define and register our settings, sections and fields.
smo_api_text_field_0_render()
and smo_api_select_field_1_render()
define HTML output of our two fields, text and select field, both belonging to the same smoPlugin
group and smo_api_settings
option — or setting — in the wp_options
table in the database.
Lastly, we define smo_api_options_page()
, which outputs the HTML for our admin options page. We incorporate the settings sections and fields in it. We’ve referred to this function at the top of our file, in the smoapi_add_admin_menu()
function, where we registered the admin (options) page.
When we now go, again, to our settings page, we’ll see that it’s no longer empty:
If we try changing and saving these fields, we will see, upon refresh, that it works! WordPress abstracts away the database transactions for us, nonces, etc.
We could further add some validation functionality, further styling of this page, and other things.
If we go to WP CLI and try to run wp option get smo_api_settings
— after we’ve changed some values for these two fields — we’ll get this:
This shows us that these two fields were saved in our wp_options
database as fields of an array, as smo_api_settings
setting.