The Complete Guide To The WordPress Settings API, Part 2: Sections, Fields, and Settings

The Complete Guide To The WordPress Settings API, Part 2: Sections, Fields, and Settings

Tutorial Details
  • Program: WordPress
  • Version: All
  • Difficulty: Beginner
  • Estimated Completion Time: Varies
This entry is part 2 of 8 in the series The Complete Guide To The WordPress Settings API

When it comes to developing WordPress Themes and Plugins, there are a number of different ways developers are creating their menus, options, and validation functionality. The thing is, there’s really only one way to properly do this within WordPress: the Settings API.

This series is aiming to be the definitive guide for how to take advantage of the WordPress Settings API so that you have a single point of reference for properly developing your themes and plugins.

In the first article in this series we took a broad look at the Settings API and why it matters. Here, we’re going to begin diving into the API and how to take advantage of everything that it offers.

We’ll take a look at the foundational units of WordPress options – sections, fields, and settings – and how to include them in the native WordPress Dashboard.


On Sections, Fields, and Settings

Before we get into writing any code, it’s important to understand the three main components of the WordPress Settings API.

  1. Fields are individual options that appear on menu pages. Fields correspond to actual elements on the screen. That is, a field is managed by a text box, radio button, checkbox, etc. Fields represent a value stored in the WordPress database.
  2. Sections are a logical grouping of fields. Whenever you’re working with multiple fields, you’re likely going to be grouping related options together – Sections represent this grouping. Furthermore, if your work includes multiple administration pages, each section often corresponds to its own menu page (though you can also add them to existing sections).
  3. Settings are registered after you’ve defined both Fields and Sections. Think of Settings as a combination of the Field and the Section to which it belongs.

At this point, don’t worry if you’re still unclear about any of the major components. We’re going to take an in-depth look at each component along with example source code that ties it all together.


A Sandbox for Our Settings

In order to get started programming against the Settings API, let’s setup a basic theme that can be used throughout this article and the rest of the series. All of the source code is available on GitHub, too.

In your local installation of WordPress, navigate to the “themes” directory and create a new, empty directory and call it “WordPress-Settings-Sandbox.” Add the following three files:

  • style.css – This is the stylesheet for the theme. It includes all meta information for the theme. It’s required by WordPress
  • index.php – This is the default template for the theme. It can be empty at first. It’s required by WordPress
  • functions.php – This is where we’ll be doing most of our work. We’ll be filling this out throughout the tutorial

Add the following code to style.css:

/*
Theme Name: WordPress Settings Sandbox
Theme URI: YOUR URI
Description: A simple theme used to showcase the WordPress Settings API.
Author: YOUR NAME
Author URI: YOUR WEBSITE
Version: 0.1

License:

 Copyright 2012 YOUR NAME (YOUR EMAIL ADDRESS)

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License, version 2, as 
  published by the Free Software Foundation.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  
*/

Next, add the following code to index.php:

<!DOCTYPE html>
<html>
	<head>	
		<title>The Complete Guide To The Settings API | Sandbox Theme</title>
	</head>
	<body>
	
		<div id="header">
			<h1>Sandbox Header</h1>
		</div><!-- /#header -->

		<div id="content">
			<p>This is theme content.</p>
		</div><!-- /#content -->

		<div id="footer">
			<p>&copy; <?php echo date('Y'); ?> All Rights Reserved.</p>
		</div><!-- /#footer -->
	
	</body>
</html>

Note that the above markup is extraordinarily simple and I do not recommend using this as a foundation for theme development. It’s tailored for this series of articles and is simply providing the means by which we will be reading values from the Settings API.

In the Themes administration screen, refresh the page and you should see the new Sandbox theme appear. Go ahead and activate it.

Theme Selection

At this point, we’re ready to get started.


Our First Set of Options

Notice in the index template above, we’ve defined three specific content regions: header, content, and footer. Using the Settings API, let’s create a “General” section containing three fields, each of which corresponds to one of the specific content regions we’ve just defined.

Before writing any code, I always find it helpful to list out exactly what I need to do. In this case, we need to do the following:

  • Define a section that will be used to group each field
  • Add three fields – one for each content region – to the section defined above
  • Register the settings with the WordPress API.

In order to avoid any massive blocks of code and to make sure that we’re covering all of our bases, we’ll be taking each of the above items point by point.

Creating the Section

In order to find our “General” section of options, we’re going to need to use the add_settings_section function of the Settings API. According to the WordPress Codex, add_settings_section requires three arguments:

  • ID – This is the unique identifier for this particular section. Note that this is the value that will be used to register each field within this section. Feel free to name it whatever you want, but I recommend making it clear for the sake of readability.
  • Title – This value will be displayed at the top of the page in the WordPress Dashboard when users are working with your options.
  • Callback – This is the name of a function that we’ll define that will render text on the screen for the function. It can be used for a variety of functionality. In the simplest case, it can be used to provide a set of instructions or description for your option page.
  • Page – This value is used to tell WordPress on which page your options should be displayed. In a future article, we’ll use this to add options to our own custom pages. For now, we’ll be adding this to the existing General Options page.

With that, let’s go ahead and define our section. Take a look at the following, commented code. We’re adding this to our functions.php file.

A word about the code snippets in this series: don’t simply copy and paste this code. Take time to read each line, see how the arguments correspond with each API function that we cover, and follow the corresponding comments to make sure you get the hang of what we’re doing:

<?php

/* ------------------------------------------------------------------------ *
 * Setting Registration
 * ------------------------------------------------------------------------ */ 

/**
 * Initializes the theme options page by registering the Sections,
 * Fields, and Settings.
 *
 * This function is registered with the 'admin_init' hook.
 */
add_action('admin_init', 'sandbox_initialize_theme_options');
function sandbox_initialize_theme_options() {

	// First, we register a section. This is necessary since all future options must belong to one.
	add_settings_section(
		'general_settings_section',			// ID used to identify this section and with which to register options
		'Sandbox Options',					// Title to be displayed on the administration page
		'sandbox_general_options_callback',	// Callback used to render the description of the section
		'general'							// Page on which to add this section of options
	);
} // end sandbox_initialize_theme_options

/* ------------------------------------------------------------------------ *
 * Section Callbacks
 * ------------------------------------------------------------------------ */ 

/**
 * This function provides a simple description for the General Options page. 
 *
 * It is called from the 'sandbox_initialize_theme_options' function by being passed as a parameter
 * in the add_settings_section function.
 */
function sandbox_general_options_callback() {
	echo '<p>Select which areas of content you wish to display.</p>';
} // end sandbox_general_options_callback
 
?>

Make sense? Generally speaking, it doesn’t look like much but navigate to your Settings menu and click on General. Scroll to the bottom of the page and you should see your new section of options.

General Settings

You can add this section to any of the pages under the Settings menu. In the above example, we’ve passed “general” as the last parameter to the add_settings_section, but if you’d like to add it to a different page, you can provide a different page title. Here’s a reference for each of the Settings pages and their corresponding key:

  • General, “general”
  • Writing, “writing”
  • Reading, “reading”
  • Discussion, “discussion”
  • Media, “media”
  • Privacy, “privacy”
  • Permalinks, “permalink”

Adding Fields

Now that we have a section defined, we can introduce a few options. Recall that in our index template we defined three specific container elements: header, content, and footer.

Though we’ll be introducing more options throughout the course of this series, today we’re going to introduce a way to toggle the visibility of each of the above elements.

Similar to what we did with the settings section, I like to list out exactly what we need to do before writing any code. Since we’re going to be toggling each of the content areas…

  • We’re going to need three options – one for each area of content
  • Since we’re toggling visibility, we can use a checkbox as our interface element

At this point, we’re ready to introduce the first settings field. To do this, we’ll use the add_settings_field function. This function takes six parameters (four required, two optional). They are as follows:

  • ID – The ID of the actual field. This will be used to save and retrieve the value throughout the theme. I recommend naming this something meaningful for improving readability of your code.
  • Title – This value applies a title to the field option on the administration page. This should be clear as it will be read by end users.
  • Callback – This is the name of the function that is used to render the actual interface element with which users will interact.
  • Page – Similar to the section we outlined, this parameter identifies on which page this option should reside. If you’re only introducing a single option, you can add it to an existing page rather than a section that you’ve defined.
  • Section – This refers to the section that you’ve created using the add_settings_section function. This value is the ID that you specified when creating your section. This is an optional parameter.
  • Arguments – This is an array of arguments that are passed to the callback function. This is useful if there is additional information that you want to include in rendering your option element. This is an optional parameter.

With that said, let’s go ahead and define our first setting field. Specifically, we’ll be introducing an option to toggle the visibility of the header.

First, we make a call to add_settings_field just below the add_settings_section function call in the initialization function we wrote in the first part of the tutorial. Review each line and the comments for each option:

// Next, we will introduce the fields for toggling the visibility of content elements.
add_settings_field(	
	'show_header',						// ID used to identify the field throughout the theme
	'Header',							// The label to the left of the option interface element
	'sandbox_toggle_header_callback',	// The name of the function responsible for rendering the option interface
	'general',							// The page on which this option will be displayed
	'general_settings_section',			// The name of the section to which this field belongs
	array(								// The array of arguments to pass to the callback. In this case, just a description.
		'Activate this setting to display the header.'
	)
);

Next, we define the callback referred to in the above function. This callback is used to render the checkbox and the description on the administration page:

/**
 * This function renders the interface elements for toggling the visibility of the header element.
 * 
 * It accepts an array of arguments and expects the first element in the array to be the description
 * to be displayed next to the checkbox.
 */
function sandbox_toggle_header_callback($args) {
	
	// Note the ID and the name attribute of the element should match that of the ID in the call to add_settings_field
	$html = '<input type="checkbox" id="show_header" name="show_header" value="1" ' . checked(1, get_option('show_header'), false) . '/>';
	
	// Here, we will take the first argument of the array and add it to a label next to the checkbox
	$html .= '<label for="show_header"> '  . $args[0] . '</label>';
	
	echo $html;
	
} // end sandbox_toggle_header_callback

As far as the checkbox is concerned, pay attention to the comments, but don’t worry too much about some of the attributes that you don’t recognize (such as a call to the checked() function). Later in this series, we’re going to take a look at each input element and their corresponding helper functions.

By now, your functions.php file should look like this:

<?php

/* ------------------------------------------------------------------------ *
 * Setting Registration
 * ------------------------------------------------------------------------ */

/**
 * Initializes the theme options page by registering the Sections,
 * Fields, and Settings.
 *
 * This function is registered with the 'admin_init' hook.
 */
add_action('admin_init', 'sandbox_initialize_theme_options');
function sandbox_initialize_theme_options() {

	// First, we register a section. This is necessary since all future options must belong to one.
	add_settings_section(
		'general_settings_section',			// ID used to identify this section and with which to register options
		'Sandbox Options',					// Title to be displayed on the administration page
		'sandbox_general_options_callback',	// Callback used to render the description of the section
		'general'							// Page on which to add this section of options
	);
	
	// Next, we will introduce the fields for toggling the visibility of content elements.
	add_settings_field(	
		'show_header',						// ID used to identify the field throughout the theme
		'Header',							// The label to the left of the option interface element
		'sandbox_toggle_header_callback',	// The name of the function responsible for rendering the option interface
		'general',							// The page on which this option will be displayed
		'general_settings_section',			// The name of the section to which this field belongs
		array(								// The array of arguments to pass to the callback. In this case, just a description.
			'Activate this setting to display the header.'
		)
	);
	
} // end sandbox_initialize_theme_options

/* ------------------------------------------------------------------------ *
 * Section Callbacks
 * ------------------------------------------------------------------------ */ 

/**
 * This function provides a simple description for the General Options page. 
 *
 * It is called from the 'sandbox_initialize_theme_options' function by being passed as a parameter
 * in the add_settings_section function.
 */
function sandbox_general_options_callback() {
	echo '<p>Select which areas of content you wish to display.</p>';
} // end sandbox_general_options_callback

/* ------------------------------------------------------------------------ *
 * Field Callbacks
 * ------------------------------------------------------------------------ */ 

/**
 * This function renders the interface elements for toggling the visibility of the header element.
 * 
 * It accepts an array of arguments and expects the first element in the array to be the description
 * to be displayed next to the checkbox.
 */
function sandbox_toggle_header_callback($args) {
	
	// Note the ID and the name attribute of the element match that of the ID in the call to add_settings_field
	$html = '<input type="checkbox" id="show_header" name="show_header" value="1" ' . checked(1, get_option('show_header'), false) . '/>'; 
	
	// Here, we will take the first argument of the array and add it to a label next to the checkbox
	$html .= '<label for="show_header"> '  . $args[0] . '</label>'; 
	
	echo $html;
	
} // end sandbox_toggle_header_callback

?>

At this point, refresh the General Settings page. You should see your checkbox with the “Header” label and a description beside the checkbox.

First Option

Unfortunately, it’s not actually saving the value to the database yet.

Registering Our Settings

In order to get our fields to actually save to the database, we need to register them with WordPress. Doing this is relatively easy – we just need to take advantage of the register_setting function.

This function accepts three arguments (two required, one optional):

  • Option Group – This is actually the name of the group of options. This can either be an existing group of options provided by WordPress or an ID that we specified when creating our own settings section. This argument is required.
  • Option Name – This is the ID of the field that we’re registering. In our case, we’re only registering a single field, but if we were registering multiple fields, then we’d need to call this function for each field we’re registering. We’ll see more on this in a moment. This argument is required.
  • Callback – This argument requires the name of a function that will be called prior to saving the data to the database. This argument is outside the scope of this article but we’ll be visiting it before the series is over. This argument is optional.

At this point, let’s register the setting that we’ve just created. Take a look at the code below. Add this line of code directly below the call to add_settings_field in the initialize function we defined earlier in the article. It’s arguably the easiest to follow out of all of the snippets in this article:

// Finally, we register the fields with WordPress
register_setting(
	'general',
	'show_header'
);

Try it out – check the checkbox, click on ‘Save Changes,’ and notice that when the page refreshes, the option has changed. Uncheck the checkbox, save, and watch it save.

Saved Option

Easy enough, right?

Adding the Final Two Options

We still need to introduce the options for toggling the visibility of the content area and the footer area. It’s almost exactly the same as how we setup the option for toggling the header.

First, let’s define the field for displaying the content area. This will go under the first call to add_settings_field:

add_settings_field(
	'show_content',
	'Content',
	'sandbox_toggle_content_callback',
	'general',
	'general_settings_section',
	array(
		'Activate this setting to display the content.'
	)
);

And let’s setup the callback function:

function sandbox_toggle_content_callback($args) {

	$html = '<input type="checkbox" id="show_content" name="show_content" value="1" ' . checked(1, get_option('show_content'), false) . '/>'; 
	$html .= '<label for="show_content"> '  . $args[0] . '</label>'; 
	
	echo $html;
	
} // end sandbox_toggle_content_callback

Next, let’s define the field for displaying the footer area:

add_settings_field(	
	'show_footer',						
	'Footer',				
	'sandbox_toggle_footer_callback',	
	'general',							
	'general_settings_section',			
	array(								
		'Activate this setting to display the footer.'
	)
);

And setup the callback for this field, too:

function sandbox_toggle_footer_callback($args) {
	
	$html = '<input type="checkbox" id="show_footer" name="show_footer" value="1" ' . checked(1, get_option('show_footer'), false) . '/>'; 
	$html .= '<label for="show_footer"> '  . $args[0] . '</label>'; 
	
	echo $html;
	
} // end sandbox_toggle_footer_callback

Finally, let’s register these two new fields with WordPress. These two function calls go at the bottom of the initialize function we defined earlier in the article.

register_setting(
	'general',
	'show_content'
);

register_setting(
	'general',
	'show_footer'
);

The final version of functions.php should look like this:

<?php

/* ------------------------------------------------------------------------ *
 * Setting Registration
 * ------------------------------------------------------------------------ */ 

/**
 * Initializes the theme options page by registering the Sections,
 * Fields, and Settings.
 *
 * This function is registered with the 'admin_init' hook.
 */ 
add_action('admin_init', 'sandbox_initialize_theme_options');
function sandbox_initialize_theme_options() {

	// First, we register a section. This is necessary since all future options must belong to one. 
	add_settings_section(
		'general_settings_section',			// ID used to identify this section and with which to register options
		'Sandbox Options',					// Title to be displayed on the administration page
		'sandbox_general_options_callback',	// Callback used to render the description of the section
		'general'							// Page on which to add this section of options
	);
	
	// Next, we will introduce the fields for toggling the visibility of content elements.
	add_settings_field(	
		'show_header',						// ID used to identify the field throughout the theme
		'Header',							// The label to the left of the option interface element
		'sandbox_toggle_header_callback',	// The name of the function responsible for rendering the option interface
		'general',							// The page on which this option will be displayed
		'general_settings_section',			// The name of the section to which this field belongs
		array(								// The array of arguments to pass to the callback. In this case, just a description.
			'Activate this setting to display the header.'
		)
	);
	
	add_settings_field(	
		'show_content',						
		'Content',				
		'sandbox_toggle_content_callback',	
		'general',							
		'general_settings_section',			
		array(								
			'Activate this setting to display the content.'
		)
	);
	
	add_settings_field(	
		'show_footer',						
		'Footer',				
		'sandbox_toggle_footer_callback',	
		'general',							
		'general_settings_section',			
		array(								
			'Activate this setting to display the footer.'
		)
	);
	
	// Finally, we register the fields with WordPress
	register_setting(
		'general',
		'show_header'
	);
	
	register_setting(
		'general',
		'show_content'
	);
	
	register_setting(
		'general',
		'show_footer'
	);
	
} // end sandbox_initialize_theme_options

/* ------------------------------------------------------------------------ *
 * Section Callbacks
 * ------------------------------------------------------------------------ */ 

/**
 * This function provides a simple description for the General Options page. 
 *
 * It is called from the 'sandbox_initialize_theme_options' function by being passed as a parameter
 * in the add_settings_section function.
 */
function sandbox_general_options_callback() {
	echo '<p>Select which areas of content you wish to display.</p>';
} // end sandbox_general_options_callback

/* ------------------------------------------------------------------------ *
 * Field Callbacks
 * ------------------------------------------------------------------------ */ 

/**
 * This function renders the interface elements for toggling the visibility of the header element.
 * 
 * It accepts an array of arguments and expects the first element in the array to be the description
 * to be displayed next to the checkbox.
 */
function sandbox_toggle_header_callback($args) {
	
	// Note the ID and the name attribute of the element match that of the ID in the call to add_settings_field
	$html = '<input type="checkbox" id="show_header" name="show_header" value="1" ' . checked(1, get_option('show_header'), false) . '/>'; 
	
	// Here, we will take the first argument of the array and add it to a label next to the checkbox
	$html .= '<label for="show_header"> '  . $args[0] . '</label>'; 
	
	echo $html;
	
} // end sandbox_toggle_header_callback

function sandbox_toggle_content_callback($args) {

	$html = '<input type="checkbox" id="show_content" name="show_content" value="1" ' . checked(1, get_option('show_content'), false) . '/>'; 
	$html .= '<label for="show_content"> '  . $args[0] . '</label>'; 
	
	echo $html;
	
} // end sandbox_toggle_content_callback

function sandbox_toggle_footer_callback($args) {
	
	$html = '<input type="checkbox" id="show_footer" name="show_footer" value="1" ' . checked(1, get_option('show_footer'), false) . '/>'; 
	$html .= '<label for="show_footer"> '  . $args[0] . '</label>'; 
	
	echo $html;
	
} // end sandbox_toggle_footer_callback

?>

Now refresh the General Settings page and notice you have all three fully functional checkboxes.

Final Options

Reading the API

What good are options if we can’t take advantage of them throughout our theme or our plugin? We need to be able to read the values in order to properly manage our new options.

To do this, we need to use the get_option function. This function accepts two arguments (one required, one optional):

  • Option ID – This argument is the ID of the field for the value you’re attempting to retrieve. This argument is required.
  • Default Option – This is the value the function will return if the function returns an empty value (such as in the case that the option is not found in the database). This argument is optional.

First, let’s try to toggle the visibility of the header. In the index template that we created earlier in this article, locate the element with the ID of header. It should look like this:

<div id="header">
	<h1>Sandbox Header</h1>
</div><!-- /#header -->

Next, let’s make a call to get_option in the context of a conditional. If the conditional evaluates to true (that is, the option has been checked on the General Settings page), then the element will be displayed; otherwise, the element will not display.

<?php if(get_option('show_header')) { ?>
	<div id="header">
		<h1>Sandbox Header</h1>
	</div><!-- /#header -->
<?php } // end if ?>

After that, hope over to the General Settings page, check the option for hiding the header element, and refresh your homepage. The header element should no longer appear.

At this point, it’s a simple matter of repeating the process for the content and footer element, too. We need to wrap the content and footer elements with conditionals that evaluate the result of get_option calls.

Take a look:

<?php if(get_option('show_content')) { ?>
	<div id="content">
		<p>This is theme content.</p>
	</div><!-- /#content -->
<?php } // end if ?>

<?php if(get_option('show_footer')) { ?>
	<div id="footer">
		<p>&copy; <?php echo date('Y'); ?> All Rights Reserved.</p>
	</div><!-- /#footer -->
<?php } // end if ?>

Revisit the General Settings page, toggle each checkbox, and refresh the theme page. Your elements should each toggle independently of one another.


Next Up, Menu Pages

That’s it, for now! We’ve taken a look at all of the functions required for introducing new sections, fields, and settings into WordPress. Of course, there’s much more to cover.

In the next article, we’ll take a look at how to add custom menu items to the WordPress menu, and how we can introduce our own pages to the WordPress Dashboard.


Related Resources

We covered a lot of material in this article. Here’s a reference for everything that we used throughout this article.


Other parts in this series:The Complete Guide To The WordPress Settings API, Part 1: What It Is, Why It MattersThe Complete Guide To The WordPress Settings API, Part 3: All About Menus
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.graterol.com Ernesto

    This topic is very interesting because with my knowledge ARRIVE prepare more more About Worpdress Thanks for the information shared Thanks for the Guide to the API

    • http://tom.mcfarl.in Tom McFarlin
      Author

      Sure thing, Ernesto!

  • http://www.metaphorcreations.com Joe

    Thanks for the great article! I have built theme option pages and custom fields for projects I’ve worked on, but all my code has been built by finding random articles online and modifying to my needs. It’s nice to learn the correct way to do things! I’m looking forward to your future articles!

    • http://tom.mcfarl.in Tom McFarlin
      Author

      Awesome, Joe – that’s exactly what I’m trying to mitigate with this series :).

  • Pingback: Wordpress | Pearltrees

  • Yehuda

    Hi

    When i use the code above and just
    Changing the input html to wp_dropdown_categories
    I see the dropdown twise to each field (double)
    Do you have an idea why ?

    • http://tom.mcfarl.in Tom McFarlin
      Author

      Without seeing more, I do not. We’re going to be talking about UI elements later in the series so stay tuned!

  • Alex

    Very nice and usefull!

    One question though: For some reason i get the feeling there’s a lot of code using the settings api like this to get just one extra option.

    I’ve created themes with lot’s of options in a custom theme options page, working with the update_option function. Creating arrays which hold the options, and with that it’s extremely easy to add options of different types ( color, input, image etc. )..

    Now i’m thinking: why should i botter to do all that extra coding with the settings api, when i could create a premium options page with much more ease?

    OR, is there something about using the settings API that i don’t know and has more benefit somehow??

    But like Joe said, it’s nice to do things the correct way, specialy since i’m in favour of creating extra unbranded wordpress functions.

    Looking forward again to part 3 :)

    • http://tommcfarlin.com Tom McFarlin
      Author

      Good questions! The Settings API…

      Offers a cleaner way of saving your options to the database. If you’re using update_option, then each option you’re using is creating a new row in the database for each option. The Settings API, when used correctly, will take each section of settings and serialize it to a single row.

      Also offers more security, when used properly, for sanitizing data before saving it to the database. If you’re not properly registering callbacks, then you’re likely leaving your options open to vulnerability for SQL injections or other malicious code.

      You get native WordPress look and feel for free in addition to having WordPress manage security values (such as the nonce values) to make sure your data is being saved in a valid session.

      Hopefully all of this helps!

      • Eben

        Nice explanation Tom, really enjoying the tutorial, have you written any more?

        • http://tommcfarlin.com Tom McFarlin
          Author

          Yep – you can see all of my articles here.

      • Andrew

        Thanks Tom, just finished part 2, looking forward to reading the rest. I also finished reading the series below and have a question.

        http://wp.tutsplus.com/tutorials/reusable-custom-meta-boxes-part-1-intro-and-basic-fields/

        The Reusable custom meta boxes series also adds fields and such, but to the admin post pages through the add_meta_box function – that I get. But what’s the difference between that and doing it this way with the settings API? Couldn’t you use the settings API to add metaboxes? Or is is only for adding fields and tabs to custom pages. I think I’m a little bit confused as to the differences between the two.

        The other series didn’t touch on sanitization at all. I’m looking forward to your insight throughout this series and hopefully I can go back and apply my knowledge to the metaboxes. Bit worried about people inserting bad things into them!

        • Andrew

          Argh another question, sorry. You mentioned storing options in 1 row in the database vs multiple. From the other series I posted above, it creates a new row for each bit of post meta. Is this ok? Or is the correct/better way to serialize it all in 1 row somehow?

  • Pingback: The Complete Guide To The WordPress Settings API, Part 3: All About Menus | Wptuts+

  • Pingback: The Complete Guide To The WordPress Settings API, Part 3: All About Menus | How to Web

  • Pingback: The Complete Guide To The WordPress Settings API, Part 4: On Theme Options | Wptuts+

  • Pingback: The Complete Guide To The WordPress Settings API, Part 4: On Theme Options | How to Web

  • http://www.moonworkspublishing.com Joe Jenkins

    I’m having a bit of a problem when I change the checkbox to a text input, as it doesn’t store the information.

    Where am I missing something on this?

    Also, is there a way to show the ‘Save Changes’ button only on the first tab?

    My admin is pretty straight forward, as it has two text inputs on the first tab, and the second tab is the user guide.

    • Tom McFarlin
      Author

      To change the checkbox to a text input, you’ll need to make sure that the value retrieves the value from the options array.

      To display the ‘save changes’ button on the form, you can wrap it in a conditional such as

      if( $active_tab === ‘whatever-tab-you-want’ ) {
      submit_button();
      }

  • Pablo

    Great tutorial Tom, it ‘s helped me understanding the wordpress API.

    • Tom McFarlin
      Author

      Glad to hear it, Pablo!

  • http://wakewebdesign.com Antoine

    Just one thing, your last image is not the right one, you put two times the same one and forgot the one with the 3 checkboxes.

    • Tom McFarlin
      Author

      Thanks – this has been amended and the project can be retrieved from GitHub.

  • Pingback: The Complete Guide To The WordPress Settings API, Part 7: Validation, Sanitisation, and Input I | Wptuts+

  • http://gopal1035.info Gopal Aggarwal

    I can’t thank you enough for this. Though I had to do a lot of Google with so many different terms to finally land the correct search terms of “Settings API”.

    You’ve saved my day!

    • Tom McFarlin
      Author

      Glad to hear, Gopal!

  • Pingback: The Complete Guide To The WordPress Settings API, Part 7: Validation, Sanitisation, and Input I | Wordpress Webdesigner

  • Pingback: My Stream | The Complete Guide To The WordPress Settings API, Part 7: Validation, Sanitisation, and Input I | My Stream

  • Pingback: The Complete Guide To The WordPress Settings API, Part 7: Validation, Sanitisation, and Input I | Shadowtek Hosting and Design Solutions

  • Pingback: The Complete Guide To The WordPress Settings API, Part 7: Validation, Sanitisation, and Input I | How to Web

  • Andrew

    Also, while I’m here, I had a thought on theme option pages. There are many theme option frameworks around as you might know. Are you for or against using one of these for creating theme option pages? Or would it be much better to roll your own?

    I noticed this one uses the WP Settings API? https://github.com/leemason/NHP-Theme-Options-Framework

    • Tom McFarlin
      Author

      Personally, I don’t use any generators.

  • Pingback: The Complete Guide To The WordPress Settings API - Tom McFarlin

  • Curtis

    Best Tut I’ve read in a while

    • Tom McFarlin
      Author

      Thanks a lot Curtis – glad to be of help!

  • http://studio88design.com Rob Myrick

    Fantastic post, and very cleanly written…..

    • Tom McFarlin
      Author

      Thank you Rob!

  • Butch

    I’m getting a Fatal error, I thought it was something that I might have done or missed typed.

    So I went back and copied all of the code to see and I’m still getting the Fatal Error that says the following

    Fatal error: Cannot redeclare sandbox_initialize_theme_options() (previously declared in C:\wamp\www\wordpress\wp-content\themes\WordPress-Settings-Sandbox\functions.php:14) in C:\wamp\www\wordpress\wp-content\themes\WordPress-Settings-Sandbox\functions.php on line 74

    can anyone help by telling me why I am getting this?

    and how to get rid of it…

    • Tom McFarlin
      Author

      This usually means that you’ve got the function declared twice some where.

      Make sure you that aren’t actually including functions.php using the PHP include method, too. WordPress will handle all of that for you.

  • Pingback: The WordPress Settings API, Part 2 | Everchanging Media

  • WPGuy

    Hey Tom,

    Fantastic tutorial !! Jus love to read all your tutorials… I am completely new to wordpress theme development and had a question regarding this tutorial….What if someone deactivates or deletes this theme? Will wordpress automatically remove all the data associated with this theme, from the database?
    Or do we need to do it programmatically?

    Apologies if you have already addressed this question somewhere else…

    • Tom McFarlin
      Author

      Nope – all of the settings will be persisted unless they completely reset the database.

  • Richard

    Hi, another +1 for an excellent article shedding some light on the Settings API, there’s a massive gap in official documentation on the subject so this is a job very well done indeed.

    I notice on Github you say “This theme is intended purely for demonstrating the Settings API and related functions. This should not be used as a foundation for other work or as a theme for blogging, content management, etc.” The code is GPL and seems very well written, any reason why not?

    Thanks again!

  • Erik

    Hey Tom,

    Awesome tutorial! Really well written and easy to follow.

    Just a slight mix up after adding the get_option for the header:

    “After that, hope over to the General Settings page, check the option for hiding the header element, and refresh your homepage. The header element should no longer appear.”

    You’ve just created the option ‘Activate this setting to display the header’, so you would have to check it to display the header or uncheck it to hide it. I know, its nitpicking, but it might be confusing to some.

    Look forward to more of your tutorials!

  • http://www.nelsondaires.com nelson

    Hi,

    this tutorial is super great, and the sanbox is priceless…

    But i’m driving nuts in how to write a callback function to create multi select checkboxes from the blog categories! Someone can help me?

    i have it almost.. is this totally wrong?

    function journal_check_categories_callback() {
    $options = get_option(‘journal_theme_blog_2_col’);

    $_cats = get_terms( ‘category’ );

    foreach( $_cats as $term ) {
    ?>
    <input type="checkbox" name="journal_theme_blog_2_col[check_categories']" value="term_id ); ?>” term_id ) . $options['check_categories'] ), true ); ?> /> name ); ?>

    <?php
    }
    }

    Thanks!

  • Pingback: Settings API in 9 steps | WordPress and me

  • http://www.nelsondaires.com nelson

    Hi,

    Can some one tell me how could I add all the categories in the web/blog as Multi-checkbox option with the code of this series tutorial?

    Thanks,
    nelson

  • Jo

    Hey TOM!!
    This article is great!!

    Those guys in wordpress should pay you for this.

    • http://wp.envato.com/ Japh Thomson
      Staff

      We paid him for it, does that count? ;)

  • http://dyce.co.za Alladyce

    Beautiful. You’re one of the best writer I’ve come across. One suggestion though, wouldn’t it be a good thing to code register_setting() just after add_settings_field() so that this two can be paired? I think it will be much more easier for future when you edit your code or something. Especially if you have a bit longer settings to play around with.

  • http://www.rsatechnoloies.in rakesh kumar

    Your image before ‘reading api’ does not contain three checkboxes. i think you just missed the image and pasted the same image for single check boxes.

  • http://kovshenin.com Konstantin Kovshenin

    Just a quick note:

    Settings are registered after you’ve defined both Fields and Sections. Think of Settings as a combination of the Field and the Section to which it belongs.

    This is not entirely true. Settings do not depend on fields or sections. You can have settings without any fields or section, and vice versa — you can have fields and sections with no actual settings. Think of a field that represents an action, the “control” can be a PayPal Donate button, but there’s no actual setting behind it, because it’s just a link.

    That said, register_setting is a useful function whether or not used in the context of settings pages. It allows us to easily put a validation callback function on options, which will be run by update_option and not necessarily triggered by a settings page.

    K

  • http://www.seojeek.com/ Alex Vallejo

    Good tutorial – You use get_option( ‘show_content’ ) which is the id of the field. Well that field’s id isn’t necessarily unique in all of the Settings API. You can have a different plugin, with a different group of options, and a field id of ‘show_content’. — That being said, I think this is incomplete and I’ve seen various ways at calling options, such as get_option( ‘option_group_name’ )['option_id'].

    In general, I’ve wasted a good week trying to sort out the confusion with something that SHOULD be easy. It’s really not, and I think that’s reflected throughout the community.

  • Pingback: Andre's Web Dev: WP Class Blog » Adding Theme Options in the WordPress Admin Dashboard

  • http://twitter.com/Tomasz_Janski Tomasz Jański

    At last I’ve understood how the get_option works. Thanks for clear and exellent explanation.

  • Sandeep

    Its a great series and awesome. Thanks a lot. Now I understand how to start using wordpress settings api

  • Pingback: An Update | Ryan Last-Harris | Designer and Web Developer