WordPress Settings API PHP Class – It has never been easier

Yesterday I was thinking to migrate my “WP User Frontend” plugins option panel to settings API which is using a manual option currently. So I thought why not write a PHP class that will solve my problems for every plugin or theme I’ll be writing? There are many existing framework like “Options Framework” and other stuffs, I wanted to keep it very simple and straight forward. So I came up with a very simple PHP class that builds your options panel with a simple file without extra hassle.

So here is how to use that class.

1. Create sections and fields array

We are going to build two array here. One contains the sections we are going to make, another one contains the fields belongs to every sections.

/**
 * Registers settings section and fields
 */
function wedevs_admin_init() {

    $sections = array(
        array(
            'id' => 'wedevs_basics',
            'title' => __( 'Basic Settings', 'wedevs' )
        ),
        array(
            'id' => 'wedevs_advanced',
            'title' => __( 'Advanced Settings', 'wedevs' )
        ),
        array(
            'id' => 'wedevs_others',
            'title' => __( 'Other Settings', 'wpuf' )
        )
    );

    $fields = array(
        'wedevs_basics' => array(
            array(
                'name' => 'text',
                'label' => __( 'Text Input', 'wedevs' ),
                'desc' => __( 'Text input description', 'wedevs' ),
                'type' => 'text',
                'default' => 'Title'
            ),
            array(
                'name' => 'textarea',
                'label' => __( 'Textarea Input', 'wedevs' ),
                'desc' => __( 'Textarea description', 'wedevs' ),
                'type' => 'textarea'
            ),
            array(
                'name' => 'checkbox',
                'label' => __( 'Checkbox', 'wedevs' ),
                'desc' => __( 'Checkbox Label', 'wedevs' ),
                'type' => 'checkbox'
            ),
            array(
                'name' => 'radio',
                'label' => __( 'Radio Button', 'wedevs' ),
                'desc' => __( 'A radio button', 'wedevs' ),
                'type' => 'radio',
                'options' => array(
                    'yes' => 'Yes',
                    'no' => 'No'
                )
            ),
            array(
                'name' => 'multicheck',
                'label' => __( 'Multile checkbox', 'wedevs' ),
                'desc' => __( 'Multi checkbox description', 'wedevs' ),
                'type' => 'multicheck',
                'options' => array(
                    'one' => 'One',
                    'two' => 'Two',
                    'three' => 'Three',
                    'four' => 'Four'
                )
            ),
            array(
                'name' => 'selectbox',
                'label' => __( 'A Dropdown', 'wedevs' ),
                'desc' => __( 'Dropdown description', 'wedevs' ),
                'type' => 'select',
                'default' => 'no',
                'options' => array(
                    'yes' => 'Yes',
                    'no' => 'No'
                )
            )
        ),
        'wedevs_advanced' => array(
            array(
                'name' => 'text',
                'label' => __( 'Text Input', 'wedevs' ),
                'desc' => __( 'Text input description', 'wedevs' ),
                'type' => 'text',
                'default' => 'Title'
            ),
            array(
                'name' => 'textarea',
                'label' => __( 'Textarea Input', 'wedevs' ),
                'desc' => __( 'Textarea description', 'wedevs' ),
                'type' => 'textarea'
            ),
            array(
                'name' => 'checkbox',
                'label' => __( 'Checkbox', 'wedevs' ),
                'desc' => __( 'Checkbox Label', 'wedevs' ),
                'type' => 'checkbox'
            ),
            array(
                'name' => 'radio',
                'label' => __( 'Radio Button', 'wedevs' ),
                'desc' => __( 'A radio button', 'wedevs' ),
                'type' => 'radio',
                'default' => 'no',
                'options' => array(
                    'yes' => 'Yes',
                    'no' => 'No'
                )
            ),
            array(
                'name' => 'multicheck',
                'label' => __( 'Multile checkbox', 'wedevs' ),
                'desc' => __( 'Multi checkbox description', 'wedevs' ),
                'type' => 'multicheck',
                'default' => array('one' => 'one', 'four' => 'four'),
                'options' => array(
                    'one' => 'One',
                    'two' => 'Two',
                    'three' => 'Three',
                    'four' => 'Four'
                )
            ),
            array(
                'name' => 'selectbox',
                'label' => __( 'A Dropdown', 'wedevs' ),
                'desc' => __( 'Dropdown description', 'wedevs' ),
                'type' => 'select',
                'options' => array(
                    'yes' => 'Yes',
                    'no' => 'No'
                )
            )
        ),
        'wedevs_others' => array(
            array(
                'name' => 'text',
                'label' => __( 'Text Input', 'wedevs' ),
                'desc' => __( 'Text input description', 'wedevs' ),
                'type' => 'text',
                'default' => 'Title'
            ),
            array(
                'name' => 'textarea',
                'label' => __( 'Textarea Input', 'wedevs' ),
                'desc' => __( 'Textarea description', 'wedevs' ),
                'type' => 'textarea'
            ),
            array(
                'name' => 'checkbox',
                'label' => __( 'Checkbox', 'wedevs' ),
                'desc' => __( 'Checkbox Label', 'wedevs' ),
                'type' => 'checkbox'
            ),
            array(
                'name' => 'radio',
                'label' => __( 'Radio Button', 'wedevs' ),
                'desc' => __( 'A radio button', 'wedevs' ),
                'type' => 'radio',
                'options' => array(
                    'yes' => 'Yes',
                    'no' => 'No'
                )
            ),
            array(
                'name' => 'multicheck',
                'label' => __( 'Multile checkbox', 'wedevs' ),
                'desc' => __( 'Multi checkbox description', 'wedevs' ),
                'type' => 'multicheck',
                'options' => array(
                    'one' => 'One',
                    'two' => 'Two',
                    'three' => 'Three',
                    'four' => 'Four'
                )
            ),
            array(
                'name' => 'selectbox',
                'label' => __( 'A Dropdown', 'wedevs' ),
                'desc' => __( 'Dropdown description', 'wedevs' ),
                'type' => 'select',
                'options' => array(
                    'yes' => 'Yes',
                    'no' => 'No'
                )
            )
        )
    );

    $settings_api = new WeDevs_Settings_API();

    //set sections and fields
    $settings_api->set_sections( $sections );
    $settings_api->set_fields( $fields );

    //initialize them
    $settings_api->admin_init();
}

add_action( 'admin_init', 'wedevs_admin_init' );

So this big chunk of code actually creating 3 settings section and within these 3 settings section, we are adding different field section with given types. e.g: text, select, textarea, checkbox etc.

Each fields array are under the same fields section key name that we are using as settings section. That way we are saying with fields belongs to which section.

Then we are creating our WeDevs_Settings_API class instance, setting the sections and fields and initialize them.

2. Register Options Page

Now it’s fairly easy. We need to just register a settings page, and display the form.

/**
 * Register the plugin page
 */
function wedevs_admin_menu() {
    add_options_page( 'Settings API', 'Settings API', 'delete_posts', 'settings_api_test', 'wedevs_plugin_page' );
}

add_action( 'admin_menu', 'wedevs_admin_menu' );

3. Display the Form

/**
 * Display the plugin settings options page
 */
function wedevs_plugin_page() {
    $settings_api = new WeDevs_Settings_API();

    echo '<div class="wrap">';
    settings_errors();

    $settings_api->show_navigation();
    $settings_api->show_forms();

    echo '</div>';
}

4. Retrieving the values

/**
 * Get the value of a settings field
 *
 * @param string $option settings field name
 * @param string $section the section name this field belongs to
 * @param string $default default text if it's not found
 * @return mixed
 */
function my_get_option( $option, $section, $default = '' ) {

    $options = get_option( $section );

    if ( isset( $options[$option] ) ) {
        return $options[$option];
    }

    return $default;
}

Now we can get those saved values by this little utility function. We can use like this echo my_get_option( 'field_name', 'section_name', 'default value' ); in our theme or plugins. If you have 4 settings section, only 4 options will be saved in the wp_options table. The options belongs to each section will be saved under those 4 option. So when you retrieve a section by get_option( 'section_name' ), you get all the section fields values under that section and they are stored as an array.

As a result, we get this -
Settings API PHP Class

So that was easy as pie!

Download Github

65 thoughts on “WordPress Settings API PHP Class – It has never been easier

  1. I just wonder what is the proper way of building a plugin with such class, but do not require extra plugin with that wraper – so include it with that created plugin, but then what if i will have two or more such plugins. So IMO there should be some check for existence of the class and if more are present, use the most recent one (if that is even possible)

    •  @kapler This PHP class is made for doing the repeatable task more simpler. If any/some plugin wants to use this class, then definitely there should be check like that class exists or not. Otherwise it’ll give a fatal error.

  2. Hello,
    Thanks for the plugin.
    But how to use the options.
    For example I want created a plugin which displays text entered in the text box in the header if yes is selected in the radio button. I have created the plugin code and settings page but how use the text entered in the text box and radio button option in the settings page???

  3. I really like it. I have a feature request however :) I would like to have introduction texts or explanations from time to time, but apparently there is no “LABEL” control. I can create it myself though, but I think it would be nice to have in your code here.

  4.  @Tareq Legend, working perfectly. Thanks for the support and thanks for writing the plugin, very handy!

  5.  @Tareq I can do that, yes, but that would be really a plus to have a “label” as well, to introduce the options of the tabs, or maybe to be able to have an “about” tab.

  6. @Jordy As settings API is WordPress native, all the option handling is done by WordPress itself. And the label is also rendered by WordPress too.

  7. Great work mate! But I still have one question, how to sanitize options before saving them. I mean i can write a simple general function to sanitize all fields in section and call it from the third argument of “register_setting()”, but what if i need to sanitize each field in one section in it’s own way… for example some fields should accept simple html tags and some not… Have any idea?

    • If you look at the WP source code, you’ll see the third parameter for register_setting( $option_group, $option_name, $sanitize_callback = '' ) is fires a filter like this: add_filter( "sanitize_option_{$option_name}", $sanitize_callback );. So you can externally add a filter and sanitize the settings, I hope that’ll work.

  8. Pingback: Mobile Theme Switcher Plugin – Redirect mobile users to an alternative theme

  9. Thank you. I have integrated your class into my plugin template sandbox. I have extended your class.settings-api.php to a settings.php.

    In this extended class I have included all the stuff you do in the big file above. So everytime I create a new plugin, I have only to change the settings.php file for the new options.

    I have added some other decorating stuff and it works great. If your plugin has a base class, make sure you create only one instance of the WeDevs_Settings_API. But it works just fine, thanks again.

  10. I am new to all of this, thanks for the headstart. I am having trouble with getting the values of the multicheck field. Any suggestions?

  11. Hi, I am just learning how to make my own plugins and i found this very useful.
    Thanks.
    I was able to create an options page and make it work in minutes. :)

    But, now i do not know how to be able to recover the saved options to use them on my plugin.
    For example:
    I want to use the text box from basic settings into the wp_head() function.
    How do i get the value to be writen on it?
    This is what i have tried but it gaves me an error:
    function wp_head() {
    $options = get_option('wedevs_basics');
    $meta = $options['textarea'];
    if ( $meta != '' ) {
    echo $meta, "\n";
    }
    }

    And i get this error:
    call_user_func_array() expects parameter 1 to be a valid callback, array must have exactly two members in ***/wp-includes/plugin.php on line 406
    Thank you very much.

  12. Hi, i was able to make that work, not sure where the mistake was, but i deleted and start over and now is working. :)
    One things is happening to me is that when i save the options i received two “Settings Saved” notifications on the top of the plugin.

    It is not affecting the plugin at all, but it is strange.

    Where could be the problem?

    Thanks again

  13. Another tip without modifying any of your classes.


    ...,
    array(
    'label' => 'Slider settings'
    ),
    ...

    When you add this you can nicely put header between fields on a single page. Now you have tabs and headers. Still a big fan of this plugin. I will hit the donate button. You’ve earned it.

  14. Hei,

    It actually gives me the error that “Options page not found”. What could I be doing wrong?

      • My plugin is in a class, could that do something wrong (like the callback has to be called differently). Could you give a comment on how to implement it in a Class oriented plugin?

        It seems very promising class, would be great to get use of it…

        • WHere it gives the error is on saving the options. Which basically means they were not regisered or something

          • Thanks! That worked.

            Another question: is there a possibility to pass in a class or an ID (so I could do some customizations, like enabling native wordpress color picker).

            M. Rettfoss

          • There is a ID for each input, automatically generated as the section_name[input_name] format. You can do what you wanted.

          • True true,

            But just for future generations, you need to escape the square brackets in jQuery:

            $(‘#mnp_settings\\[button_color\\]‘);

            I would still prefer not doing that:)

            M. Rettfoss

  15. Hi again,

    Would it be possible to call sanitize callback on register_settings. I see in your class that the argument is not there, so I was wondering if I could add it (maybe with some conditional checking if function exists), but then I don’t want to edit your class with new case specific callbacks. Is it possible to call external callback from within (your) class? My plugin is enclosed in class.

    Thanks! Otherwise your class is a piece of art! I really appreciate you wrote it. Do you accept donations or something?

    M.

    • Yeah, I didn’t added any callback on register_settings, but you could easily add one. WordPress automatically gives you this filter if you didn’t pass any callback: add_filter( "sanitize_option_{$option_name}", $sanitize_callback );. If you think this should be in the class, please fork the class and give me a pull request. I’ll be happy to have this here.

      Otherwise your class is a piece of art! I really appreciate you wrote it

      Ahh, you are kind enough to say it! :) If you want to donate, there is a donate button in the sidebar. You can use it.

  16. Is this currently working under WP 3.5.1?

    Also, just curious, is there documentation of which files to insert the code snippets in this post?

    I kinda need a starting point.. thanx :)

  17. Great framework, Tareq. I have been working on one very similar. I’ve forked you on GitHub and look forward to working with you in the future on some changes I have in mind.

    - Jesse

  18. Sorry Tareq…

    I’m trying to add a sanitize filter as you said, but I must be stupid or else because I can’t do it works.
    Can you help me?

    Thanks! And you know: sorry for my english…

  19. Pingback: Change custom post type slug from plugin options

  20. Hi Tareq,

    Is there option to add some custom content to tab.
    I need to include some custom things on options page.
    Would like to add custom action hook, so I can hook into second tab.

    Thanks in advanced

    BR
    Vlado

  21. Hi,

    Nice work. But i have problem. how i can call the field value?

    When i tried

    function wp_settingapi_hook() {

    ?>

    body{background:}

    <?php

    }
    add_action('wp_head', 'wp_settingapi_hook');

    I want to change of my body background-color using a field. but i faild

  22. function admin_menu() {
    add_options_page( ‘Settings API’, ‘Settings API’, ‘delete_posts’, ‘settings_api_test’, array($this, ‘plugin_page’) );
    }
    ‘delete_posts’—>’manage_options’

  23. This is by far the best settings API class I have found. Simple native and easy to use. BRILLIANT! Thank you so much.

  24. Pingback: Default values automatically save in database when plugin will be activated

  25. Dear Tareq vaiya ami apnar setting api ti use koresi abong ati shothik vabe kaj korse kintoo ami value get korar shomoy condition use korte parsina like if(exist){something} please help me how can i do this

  26. Dear Tareq Hasan vai, It’s a awesome work. Very helpful and time saving. Can you Please add some more field like, wysiwyg, taxonomy or post-type select, group file upload etc.

    Thanks in advance.

Leave a Reply