I hope my question isn't out of the scope of this website and that someone can help me with it.

I'm currently studying the WP Settings API and I'm wondering how to create a form management section which will allow you to do the following:

  • Create fields
  • Delete fields
  • Change field properties (type, default value, etc)
  • Change order of fields

I do know how to create the mentioned form and all the features, I`m just not sure about the correct way to save the desired form format (fields order, field properties).

First thing that came to my mind was to create hidden fields and modify their values using javascript but something tells me that there should be a better solution for this situation.

Any suggestion is appreciated!

  • I've noticed that you can create a field through the Settings API and save it as an array. So you can have multiple fields like this: <input type="text" class="form_field_title" name="form_field[1][title]" /> <input type="text" class="form_field_title" name="form_field[2][title]" /> And they will all be saved under the same setting on your database as an array. Commented Jan 22, 2014 at 12:10

1 Answer 1


When you call register_setting, the third parameter is the sanitize callback function. You can do whatever data manipulation you need in that function, in order to arrange the user input into the format you need for your code. So after the data validation (integers are integers, sanitize text fields, etc.), you can retrieve the current option value and add or delete from there according to the user input.

You can also do some manipulation in javascript before the data is submitted, but be aware that javascript can be turned off, so you would have to deal with two different types of input. Therefore, this usually isn't a good idea.

The following code uses javascript in the page to create and delete items in a list, and puts the entire list into one input when the Save button is clicked. The plugin is dependent on the javascript for the content of that one input, and saves it in JSON format (no manipulation in PHP, only in javascript). The sanitize callback creates an array of arrays so that the user can save multiple named lists. It's not quite the same as your question, but similar and tested.

register_setting( 'example_group', 'example_option_name', 'example_settings_validation' );

function example_settings_defaults( $theme ) {   // provide default option values
    if ( 'weaver-ii' == $theme )
        $page = 'themes.php?page=WeaverII';
    else if ( 'aspen' == $theme )
        $page = 'themes.php?page=Aspen';
    else $page = '';
    $label = 'new';
    $used = sanitize_key( $label );
    $entry = array( 'color_class'=>'color', 'user_label'=>$label, 'last_modified'=>'', 'tie_list'=>json_encode( array() ) );
    $new = array( 'theme_page'=>$page, 'last_used'=>$used, 'entries'=>array() );
    $new['entries'][$used] = $entry;
    return $new;

function example_settings_validation( $input ) {    // called by Settings API on a Save
    $clean = get_option( 'example_option_name', example_settings_defaults() );
    $label = sanitize_text_field( $input['user_label'] );
    if ( isset( $input['action_delete'] ) ) {  // user clicked Delete list
        if ( isset( $input['user_label'] ) ) {
            $key = sanitize_key( $label );
            unset( $clean['entries'][$key] );
            if ( 0 == count( $clean['entries'] ) ) {
                $new = example_settings_defaults( 'xx');
                $clean['entries'] = $new['entries'];
                $clean['last_used'] = $new['last_used'];
            else if ( $key == $clean['last_used'] ) {  // check if they deleted last used
                $keys = array_keys( $clean['entries'] );
                $clean['last_used'] = $keys[0];
            add_settings_error('deleteID', 'action_delete', $label.__(' entry deleted.', 'xmpl'), 'updated');
    if ( isset( $input['action_save'] ) ) {  // user clicked Save
        $clean['theme_page'] = sanitize_text_field( $input['theme_page'] );
        $entry = array();
        $entry['color_class'] = sanitize_html_class( $input['color_class'] );
        $entry['tie_list'] = sanitize_text_field( $input['tie_list'] );
        $entry['last_modified'] = current_time( 'mysql' );
        if ( empty( $label ) ) $label = 'new';
        $entry['user_label'] = $label;
        $clean['last_used'] = sanitize_key( $label );
        $clean['entries'][$clean['last_used']] = $entry;
        add_settings_error('saveID', 'action_save', $label.
            sprintf( _x(' entry saved at %s','MySQL timestamp', 'xmpl'), $entry['last_modified'] ), 'updated');
    return $clean;

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.