• Skip to main content
  • Skip to primary sidebar
  • About
  • Contact
  • Resources
  • Blog
    • Easy Digital Downloads
    • General
    • Genesis Framework
    • jQuery/JavaScript
    • Project Management
    • WordPress Functions
    • WordPress Plugin Development
  • Army Lessons

Scott DeLuzio

WordPress Development Tutorials

Intro to WordPress Plugin Development: Adding a Settings Page

August 14, 2017 Scott DeLuzio Leave a Comment

This entry is part 9 of 12 in the series Intro to WordPress Plugin Development

Intro to WordPress Plugin Development
  • Intro to WordPress Plugin Development
  • Intro to WordPress Plugin Development: Best Practices
  • Intro to WordPress Plugin Development: Using Filters
  • Intro to WordPress Plugin Development: Using Actions
  • Intro to WordPress Plugin Development: Register Custom Post Types
  • Intro to WordPress Plugin Development: Shortcodes
  • Intro to WordPress Plugin Development: Loading Scripts and Styles
  • Intro to WordPress Plugin Development: Add a Menu to Dashboard
  • Intro to WordPress Plugin Development: Adding a Settings Page
  • Intro to WordPress Plugin Development: Sanitize and Validate Data
  • Intro to WordPress Plugin Development: Object Oriented Programming
  • Intro to WordPress Plugin Development: Separate Into Multiple Files

In the previous part of the Intro to WordPress Plugin Development series, we talked about how to add menu links to the dashboard. We briefly touched on adding content to the page that the link points to, but that content isn’t particularly useful. What we need is a way for users to interact with our plugin. We’ll need a settings page where users can type text into text boxes, or text areas, choose options from select menus, radio buttons, or check boxes. Not only do they need to provide input into those fields, we also need to be able to save that information to the database.

Register Setting Fields

There are two ways we can register our setting fields. We can register every field individually, or we can register one field that will save all of the data to the database in an array. There are pros and cons to both options, which we’ll look at individually.

Register Setting Fields Individually

Pros:

  • Easier to retrieve data as it is saved in the database as plain text
  • Descriptive setting name makes it easier to identify what the variable will contain

Cons:

  • Need to register each field separately
  • Retrieving the data for display or modification requires a database query for each setting
  • Can be cumbersome if there are a lot of settings

Register One Setting Field for All Settings

Pros:

  • Easier to register settings with one line of code
  • Retrieving settings data requires only one query to the database
  • Allows other plugins to extend your settings code without having to register new settings

Cons:

  • Must retrieve all data from the database any time you need to display, or update the setting values
  • Individual setting values are not easily updated through update_option without updating all other values in the array

How to register settings individually

In order to register our settings we’ll use the register_setting function.

function sd_register_settings(){
	register_setting( 'sd_option_group', 'first_name', 'sd_callback_function_name' );
	register_setting( 'sd_option_group', 'email_address', 'sd_callback_function_email' );
	register_setting( 'sd_option_group', 'favorite_team', 'sd_callback_function_team' );
}
add_action( 'admin_init', 'sd_register_settings' );

function sd_register_settings(){ register_setting( 'sd_option_group', 'first_name', 'sd_callback_function_name' ); register_setting( 'sd_option_group', 'email_address', 'sd_callback_function_email' ); register_setting( 'sd_option_group', 'favorite_team', 'sd_callback_function_team' ); } add_action( 'admin_init', 'sd_register_settings' );

You’ll notice that we had to call the register_setting function three times. Why did we need to do that?

Simply, because we are registering three settings individually here.

The function takes three parameters.

  • Option Group: This is a name given to the group of all fields. This is required in order to be able to properly save the form you will set up later on.
  • Option Name: This is the name given to the option you are creating. In the example above, I used first_name, email_address, and favorite_team.
  • Sanitize Callback: The name of a function that will sanitize the values that you are trying to save. Sanitizing values ensures that only the data you want or are expecting to be saved are the values that are saved. Think about an email address field – you wouldn’t want a phone number entered there, right? Sanitizing the data is a good practice to prevent the wrong data from being submitted to your settings.

Build the form to save our settings

So far we really haven’t done much. We’ve told WordPress what the settings are that we are expecting, but not much else. Now we can build the form that will hold the settings fields and ultimately save the data to the database.

Let’s build the form.

<?php
// this function is the callback function that displays content on our menu's page
function sd_display_top_level_menu_page(){
 
	$teams = array( 'Baltimore Orioles', 'Boston Red Sox', 'Chicago White Sox', 'Cleveland Indians', 'New York Yankees' );
	?>
	<form method="post" action="options.php">
		<?php settings_fields( 'sd_option_group' ); ?>
 
		<table>
			<tr>
				<td>Your First Name:</td>
				<td><input type="text" name="first_name" value="<?php echo get_option( 'first_name' ); ?>" /></td>
			</tr>
			<tr>
				<td>Your Email:</td>
				<td><input type="text" name="email_address" value="<?php echo get_option( 'email_address' ); ?>" /></td>
			</tr>
			<tr>
				<td>Your Favorite Team:</td>
				<td>
					<select name="favorite_team">
						<?php foreach ( $teams as $team ){
						echo '<option value="' . $team . '" ' . selected( $team, get_option( 'favorite_team' ) ) . '>' . $team . '</option>';
						} ?>
					</select>
				</td>
			</tr>
			<tr>
				<td colspan="2"><?php echo submit_button(); ?></td>
			</tr>
		</table>
 
	</form>
	<?php
}

<?php // this function is the callback function that displays content on our menu's page function sd_display_top_level_menu_page(){ $teams = array( 'Baltimore Orioles', 'Boston Red Sox', 'Chicago White Sox', 'Cleveland Indians', 'New York Yankees' ); ?> <form method="post" action="options.php"> <?php settings_fields( 'sd_option_group' ); ?> <table> <tr> <td>Your First Name:</td> <td><input type="text" name="first_name" value="<?php echo get_option( 'first_name' ); ?>" /></td> </tr> <tr> <td>Your Email:</td> <td><input type="text" name="email_address" value="<?php echo get_option( 'email_address' ); ?>" /></td> </tr> <tr> <td>Your Favorite Team:</td> <td> <select name="favorite_team"> <?php foreach ( $teams as $team ){ echo '<option value="' . $team . '" ' . selected( $team, get_option( 'favorite_team' ) ) . '>' . $team . '</option>'; } ?> </select> </td> </tr> <tr> <td colspan="2"><?php echo submit_button(); ?></td> </tr> </table> </form> <?php }

As you can see this is a pretty basic form with two text inputs and a select option menu. You’ll also notice the settings_fields( 'sd_option_group' ). See how the group name given here matches the first parameter in the register settings functions above? This is how WordPress makes the connection between the registered settings with the settings in the form. The settings_fields function provides all of the hidden fields that your settings page will need.

How to register one settings field for all options

This is going to be very similar to our previous function where we registered our settings. Except for this time, we’re only going to register one setting.

function sd_register_settings(){
	register_setting( 'sd_option_group', 'sd_fields', 'sd_callback_function' );
}
add_action( 'admin_init', 'sd_register_settings' );

function sd_register_settings(){ register_setting( 'sd_option_group', 'sd_fields', 'sd_callback_function' ); } add_action( 'admin_init', 'sd_register_settings' );

What about the other fields? Why do we need a separate field?

The other fields we created before are going to be stored inside of this new field. The values that the user enters will be saved as a serialized data array rather than as a string.

The new settings page content

<?php
// this function is the callback function that displays content on our menu's page
function sd_display_top_level_menu_page(){
 
	$settings 	= get_option( 'sd_fields' );
	$teams 		= array( 'Baltimore Orioles', 'Boston Red Sox', 'Chicago White Sox', 'Cleveland Indians', 'New York Yankees' );
	?>
	<form method="post" action="options.php">
		<?php settings_fields( 'sd_option_group' ); ?>
 
		<table>
			<tr>
				<td>Your First Name:</td>
				<td><input type="text" name="sd_fields[first_name]" value="<?php echo $settings[ 'first_name' ]; ?>" /></td>
			</tr>
			<tr>
				<td>Your Email:</td>
				<td><input type="text" name="sd_fields[email_address]" value="<?php echo $settings[ 'email_address' ]; ?>" /></td>
			</tr>
			<tr>
				<td>Your Favorite Team:</td>
				<td>
					<select name="sd_fields[favorite_team]">
						<?php foreach ( $teams as $team ){
						echo '<option value="' . $team . '" ' . selected( $team, $settings[ 'favorite_team' ] ) . '>' . $team . '</option>';
						} ?>
					</select>
				</td>
			</tr>
			<tr>
				<td colspan="2"><?php echo submit_button(); ?></td>
			</tr>
		</table>
 
	</form>
	<?php
}

<?php // this function is the callback function that displays content on our menu's page function sd_display_top_level_menu_page(){ $settings = get_option( 'sd_fields' ); $teams = array( 'Baltimore Orioles', 'Boston Red Sox', 'Chicago White Sox', 'Cleveland Indians', 'New York Yankees' ); ?> <form method="post" action="options.php"> <?php settings_fields( 'sd_option_group' ); ?> <table> <tr> <td>Your First Name:</td> <td><input type="text" name="sd_fields[first_name]" value="<?php echo $settings[ 'first_name' ]; ?>" /></td> </tr> <tr> <td>Your Email:</td> <td><input type="text" name="sd_fields[email_address]" value="<?php echo $settings[ 'email_address' ]; ?>" /></td> </tr> <tr> <td>Your Favorite Team:</td> <td> <select name="sd_fields[favorite_team]"> <?php foreach ( $teams as $team ){ echo '<option value="' . $team . '" ' . selected( $team, $settings[ 'favorite_team' ] ) . '>' . $team . '</option>'; } ?> </select> </td> </tr> <tr> <td colspan="2"><?php echo submit_button(); ?></td> </tr> </table> </form> <?php }

Here, you can see a difference in how we are retrieving the data. In the first example, we have get_option three times. In this version, we only have it once. This means there are two fewer queries to the database to get the same exact data.

Next, you’ll notice that the input names are different. In the first example, we just used the name of the field (first_name, email_address, favorite_team). In the second example, we only used the one field we registered (sd_fields), but we used it as an array. So instead of a static name as we had in the first example, we have sd_fields[first_name], sd_fields[email_address], sd_fields[favorite_team].

Let’s see what all of our settings look like in the wp_options table.

The first three options you see in the image are what was saved from the first example.

The last option is what was saved from the second example. See how the last example has a bunch of strange characters and letters? That’s how WordPress saves serialized data in an array. If you happen to be looking at this data in your database, do not edit serialized data directly in the database. The letters, numbers, and symbols all mean something and if you don’t edit it correctly you will make your data impossible to read.

Accessing the data

Now that your settings are saved in the database, you can access the data elsewhere on the site by using the get_option function. Use this, and pass the setting’s name like this: get_option( 'sd_fields' );. Then you can do whatever you want with the data. You can display it on the screen, use it in a conditional check, or in some other function.

Sanitizing Data

We’ll look at how to sanitize the input and output of data that is submitted through our settings page in the next section of this series.

Series Navigation<< Intro to WordPress Plugin Development: Add a Menu to DashboardIntro to WordPress Plugin Development: Sanitize and Validate Data >>

Tutorial Series

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Primary Sidebar

Come say hi!

  • Facebook
  • GitHub
  • Instagram
  • LinkedIn
  • Twitter
  • YouTube

Tweets by scottdeluzio

My Products

Conditional Checkout FieldsFull Screen Background ImagesQuick CheckoutWP1099

I use affiliate links throughout this site and may earn a commission if you purchase through my links. I do not link to products or services that I do not trust, or use myself.
© 2025 · Scott DeLuzio · Built on the Genesis Framework