I am asking for advice on best practices on how to write this code. Currently I have simple theme options with text fields, outputting the info in my template. I am currently using this code for the settings api and sanitization of the plain text. My questions is, an additional settings field is a website field, and also an email field. I am not sure if I have to create another entire theme option, section and field so I can directly sanitize the registered settings individually (and properly for each type), or if this can all be combined within the same oem_theme_profile_options sanitization. I am not the best php guy, yet. So figuring this out in terms of best practice will help educate me for the future and not lead me to create multiple options in the database.

function oem_theme_initialize_profile_options() {

        if( false == get_option('oem_theme_profile_options')) {

                'Profile Options',

                            'oem_theme_sanitize_profile_options' // Here is where all these options get sanitized the same.
} // end of oem_theme_initialize_profile_options

add_action('admin_init', 'oem_theme_initialize_profile_options');

function oem_profile_options_callback() {
        echo '<p>Provide the URL to the profile networks you\'d like to display</p>';
} // end oem_profile_options_callback

function oem_personal_name_callback() {

        // First, we read the profile options collection
        $options = get_option('oem_theme_profile_options');

        // Next, we need to make sure the elment is defined in the options. If not, we'll set an empty string.
        $url = '';
        if (isset( $options['personal_name'] )) {
                $url = $options['personal_name'];

        // Render the output
        echo '<input type="text" id="personal_name" name="oem_theme_profile_options[personal_name]" value="' . $options['personal_name'] . '" />';
} // end oem_personal_name_callback

Sanitization of text

function oem_theme_sanitize_profile_options($input) {

        //Define the array for the updated options
        $output = array();

        // Loop through each of the options sanitizing the data
        foreach ($input as $key => $val) {

                if( isset($input[$key]) ) {
                        $output[$key] = strip_tags( stripslashes($input[$key]));
                } // end if
        } // end foreach

        return apply_filters( 'oem_theme_sanitize_profile_options', $output, $input );
} // end oem_theme_sanitize_profile_options
  • This question seems to have an over-broad scope. I'm seeing multiple questions: how to sanitize email addresses, how to sanitize URLs, how to sanitize text, how to pass multiple options/data types to the same sanitization callback, etc. Commented May 3, 2012 at 14:42
  • 1
    Hey @ChipBennett, I am aware of how to sanitize text vs. email vs. web address. My question is if I can sanitize them within the same section, i.e., when the register_settings sanitizes the section settings, or if I should create a new set of settings for the email, and again for the web address, to sanitize them separately. Hope this clears things up.
    – chris_s
    Commented May 3, 2012 at 15:56

2 Answers 2


Instead of using add_settings_section() and add_settings_field() every time, create a function that returns an array of options for example:

function my_theme_options() {
$options = array();

$options[] = array(
                'id' => 'ID',
                'title' => 'Title',
                'type' => 'text_field', // use this value to sanitize/validate input
                'validate' => 'url' // use this value to validate the text as url
                // add as much as you need like description, default value ...

$options[] = array(
                'id' => 'ID_2',
                'title' => 'Title',
                'type' => 'text_field',
                'validate' => 'email' // use this value to validate the text as email
                // add as much as you need like description, default value ...

// every time you want to add a field you'll use this function an create a new array key $options[] = array();

return $options;


using this function we can register each field with a foreach loop that will use add_settings_field()

now using this function you can create one callback function for register_setting() and use switch to validate the input for example:

// this should be the callback function of register_setting() (last argument)
function validate_settings($input) {
$options = my_theme_options(); // we'll set $options variable equal to the array we created in the function before

$valid_input = array(); // this will be the array of the validated settings that will be saved to the db, of course using one array for all options.

foreach ($options as $option) {
    switch ( $option['type'] ) { // $option['type'] where type is the key we set before in my_theme_options()
        case 'text_field':
            // inside we'll create another switch that will use the validate key we created in my_theme_options()
            switch( $option['validate'] ) {
                case 'url':
                    // validate url code


                case 'email':
                    // validate email

                // create a default for regular text fields
                    // default validation

        case 'textarea':
            // your validation code here

        // you get the idea just keep creating cases as much as you need
    }// end switch
}// end foreach

return $valid_input;

at the end of each case to save the value to $valid_input array

$valid_input[$option['id']] = $input[$option['id']]

for example for validating the url use:

if ( preg_match('your regex', $input[$option['id']]) ) {
    $valid_input[$option['id']] = $input[$option['id']];

you can also create a function just like the options function but for sections and create a foreach loop that will use add_settings_section(), you get the idea this will be much easier for you, you'll save a lot of time later when you want to add new settings fields and section. hope that helps :)


I guess I would first refer you to the Codex section on Data Validation. There, you will find a ton of useful built-in functions for sanitizing URLs and other input fields, including a check for a valid email (is_email()) though it doesn't actually sanitize it.

Then, since you're getting an associative array in $input, consider writing a switch statement within oem_theme_sanitize_profile_options() if you wish to isolate certain inputs to be dealt with as special cases.

Consider using add_settings_error() if an input field (such as the email field) is invalid.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.