A complete, versatile options page class for any WordPress plugin

Building an options page for a plugin can be a daunting prospect – you want to build it in a way that works for your plugin, but also so that it works well within the WordPress UI. Many plugin authors get this painfully wrong and build incredibly unfriendly options pages that look terrible and really don’t fit into the WordPress dashboard design at all.

After putting loads of work into refactoring Seriously Simple Podcasting for the v2.0 release, I’ve developed a single class that will help you to create a versatile and user-friendly options page for your plugin that fits neatly into the WordPress dashboard. All you need to do is add this class to your plugin and modify the array of settings to handle the data that your plugin needs.

This isn’t a tutorial post, so I’m not going to walk you through this step by step, but if you use the class below you can create a WordPress options page with every type of field possible with almost no effort on your part. The field types that this class can create are:

  • Text field
  • Password field
  • Secret text field (where the saved data is not displayed on the page)
  • Text area
  • Single checkbox
  • Multiple checkboxes
  • Select box
  • Multiple select box
  • Radio buttons
  • Number field
  • Colour picker (using WordPress’ built-in colour picker script)
  • Image upload (that saves the image to your site’s media library)

I have included demo fields in the class so you can see how each field type works and what parameters you need to define for each field type – all you need to do is delete these fields and create your own.

The class uses all the WordPress Settings API functions, so it does things in the “correct” way. It also includes a mini-navigation that uses Javascript to show & hide the relevant sections.

You will find the class, along with its associated Javascript file below, but if you want to see it all in action in the context of a full plugin you can check out my WordPress Plugin Template that includes this same code. For a quick overview of what the resulting options page will look like, here’s a handy screenshot (click to enlarge):

Options page
The options page that is generated by this class

Here is the class in its entirety:

And here is the Javascript file that you will need to manage everything. You will need to save this inside your plugin in this folder: /assets/js/admin.js

To add this options page to your plugin, simply add this line to your plugin’s index file after you have added an include for the class file:

Once you have added all this code you will find the new options page in the dashboard menu by going to Settings > Plugin Settings.

The options that are saved from this page use the $settings_base variable in the class (in this case, ‘wpt_‘)followed by the id field of each setting for their name. So the option name for the first field would be ‘wpt_text_field‘, which you can fetch using get_option( 'wpt_text_field' );.

If you can think of any other field types that you think should be included in this class then let me know in the comments.

This site is hosted by SiteGround - running on their incredibly fast and super secure platform that is uniquely tailored for WordPress hosting. Moving my site to SiteGround was the best decision I ever made for it - you should do the same. Today.

15 thoughts on “A complete, versatile options page class for any WordPress plugin”

  1. Great work, just came in handy for my very first plugin. I learned a lot about WP from friendly people like you who are willing to share their knowledge. As for your question about enhancements: how about having some sort of repeater? This would give us the ability for having “sets of settings”. Example: a playlist for an mp3 player, where each entry could for example have a title, a cover picture, etc.

    Another thought: how about storing all settings in an array into the db, instead of having multiple db calls?

    Grettings from germany

    1. In addition to the above: just found your fantastic wordpress plugin template on Github and came up with another idea on this: why not separate the field output logic? So we could use the different field types for the custom post type metaboxes as well.

      1. Thanks for the great feedback Andre! I’ll look into the idea of a ‘set’ of settings like you mention – might be a nice little enhancement. As for storing the options in a single array instead of multiple DB calls, I chose not to do that because when you are calling the options on the frontend it’s not always beneficial to call every single option when all you need is a single option. I’m not sure of the numbers with regards to performance, but I generally favour multiple options instead of one global array.

        I really like the idea of separating out the field logic so it’s usable for custom post types as well – I’ll look into enhancing the template to handle that as I think it would be a very valuable upgrade :)

        1. Glad you like my ideas. I think your template is a valuable foundation for every plugin coder, especially for beginners like me. I definitive stick with this post and will refractor my mp3 player plugin with your template as a base, especially after your next update ;-)

          For the database calls: I just was a bit concerned about the amount of database calls for each plugin. Since I love the progress in my WP coding skills, i am quite sure that there will be a lot more plugin stuff from me in the future. Right now I am working on a versatile solution to play mp3 files in a WP site, comes with different flavors like single player, footer player ith playlist, etc. Complete with custom post type. I am damn proud about my first plugin. At the moment I am struggling with a single bit: I somehow need to hook into the file upload process. First for ensuring that there are only mp3 files ready, second because I want to create preview files of the uploaded mp3 files. I have a fantastic class for hat in my arsenal, that I have allready used for another project.

          Thanks for your effort, can’t wait to see the progress in your template. Keep me informed please ;-)

  2. Hi. Thanks for this. I have a question about multi-select options.

    I need to generate the options dynamically according to the given site’s user roles. So:

    ‘id’ => ‘multi_select_box’,
    ‘label’ => __( ‘A Multi-Select Box’, ‘plugin_textdomain’ ),
    ‘description’ => __( ‘A standard multi-select box – the saved data is stored as an array.’, ‘plugin_textdomain’ ),
    ‘type’ => ‘select_multi’,
    ‘options’ => array( ‘linux’ => ‘Linux’, ‘mac’ => ‘Mac’, ‘windows’ => ‘Windows’ ),
    ‘default’ => array( ‘linux’ )

    … the options array would need to be built from another foreach and stored in a variable I guess. Here’s the foreach to generate the user roles:

    global $wp_roles;
    $all_roles = $wp_roles->roles;
    $editable_roles = apply_filters(‘editable_roles’, $all_roles);
    foreach($editable_roles as $role=>$theroles){
    echo ”.$wp_roles->role_names[$role].”;

    How could I do this and plug it into the options array? Thanks for your time.

    1. Hi Thom,

      All you need to do is save the array of user roles as a variable in this format array( 'role' => 'Role Name' ). If you’re not sure how to do that then Google should be able to help you out :)

  3. Hi,
    Thanks for this great plugin template. I am starting my first plugin with your template. I have a question though. What the “validation callback for field” is doing? Can you explain it for me?

    public function register_settings () {
    if( is_array( $this->settings ) ) {
    foreach( $this->settings as $section => $data ) {

    // Add section to page
    add_settings_section( $section, $data[‘title’], array( $this, ‘settings_section’ ), ‘html_data_table_settings’ );

    foreach( $data[‘fields’] as $field ) {

    // Validation callback for field
    $validation = ”;
    if( isset( $field[‘callback’] ) ) {
    $validation = $field[‘callback’];

    // Register field
    $option_name = $this->base . $field[‘id’];
    register_setting( ‘html_data_table_settings’, $option_name, $validation );

    // Add field to page
    add_settings_field( $field[‘id’], $field[‘label’], array( $this, ‘display_field’ ), ‘html_data_table_settings’, $section, array( ‘field’ => $field ) );

    1. The validation callback is a way of validating the submitted form data before saving it. You can create a function that checks the content of the submitted field and performs any action you like on that content before saving it to the database. A good example of this would be if you are asking people to save a URL in one of the fields – using the validation callback you can run the esc_url() function on the submitted text to make sure that it is saved as a properly formatted URL.

  4. Hey, nice job, this is fantastic!
    Im new in this whole backend hardcore programming, and I have a problem with your template. When I click “upload an Image” it just doesnt add it, if I choose a file in my pc it sends an error, and if I choose the “Use one in wordpress” or something like that option, it keeps “buffering” forever. I dont know if there is an issue with your code, i dont know perhaps some function got deprecated, or if I made a mistake. But I followed every step, and the other things are working wonderfully, hope you read this and know how to solve it.

    And of course, Thank you for sharing this, this is amazin!


  5. When I call for option value in plugin file using get_option(‘id’); this is not work means value does not show. please help how can i get option value right way. Thank you!

  6. Thanks Hugh, it saved time.
    JS code was giving me error when I tried to upload an attachment. Adding a “var” before attachment variable fixed it.

    In case we have plenty of options to offer, we should save them as an array. Do you have any idea how can I change your code to save all options in a single array i.e. one entry in wp_options table with serialized data?

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>