How To Use Screen Options in your WordPress Plugin

If you have used WordPress, you have almost certainly noticed the ‘Screen Options’ and ‘Help’ tabs located in the upper-right of just about every WordPress admin screen. These tabs let users get help or manage settings related to their current page. For example, while on the dashboard page, the number of columns can be set, as well as the sections of content to show. While on the posts page, specific columns can be enabled or disabled, and the number of posts to show per page can be set. These options are user-specific, and are stored in the WordPress database so that the next time the user logs in, their settings are retained.

This is a fantastic feature to utilize in your plugins. It makes much more sense to set options that apply to a specific page from the page itself, rather than having to hunt down the option on a separate settings page, and since these tabs are used throughout the admin area of WordPress, users should feel right at home setting various options using this interface.

Goals of This Tutorial

This tutorial is going to focus on creating an option to set the number of listings per page from within the ‘Screen Options’ tab. I am assuming you understand the basics of the PHP language as well as how to develop WordPress Plugins

Step 1: Add Action to Page Load Action

First, we need to tell WordPress that we want to add a screen option for the specific page.  To do this, we will hook a function into the load action for our plugin page. Before we can do that however, we need to know our page’s hookname. When you added your page, you probably did something similar to the following:

add_menu_page( $pg_title, $menu_title, $cap, $slug, $function );

Luckily, both the add_menu_page() and add_submenu_page() functions return the hookname of the pages that are created. We can modify the above code as shown below in order to get the hookname of our plugin’s page.

$hook = add_menu_page( $pg_title, $menu_title, $cap, $slug, $function );
add_action( "load-$hook", 'cmi_add_option' );

By setting $hook to the value of the function, it now contains the hookname of our page. All we need to do now is use the WordPress add_action() function to hook our own function (cmi_add_option) into the load action of our plugin’s page. We will use this function to tell WordPress what options we want to appear in the Screen Options tab.

Step 2: Add Our Option to the Screen Options Tab

To add an option to the screen options tab, we cam use the WordPress function add_screen_option(). This function takes two parameters, $option and $args.

The $option Parameter

The $option argument should contain the type of option we are adding. WordPress has a few types built in that we are able to use. In this case, we are going to take advantage of the ‘per_page’ type that WordPress has set up. This makes our life a lot easier by having WordPress generate the output for the option as well as dealing with saving the option to the database.

The $args Parameter

The $args parameter will contain any arguments that the specific $option required. In the case of the ‘per_page’ option type, we are expected to pass three arguments: ‘label’, ‘default’ and ‘option’.

‘label’ should contain a label that could be used to describe the items we are working with. If you have a list of people, you could set this to ‘People’; I chose to set the value to ‘Movies’ since I have a list of movies to filter. Take a look at the picture below to see how this is used in the Screen Options tab.

Example of per_page label usage

‘default’ should be set to the value you want to be the default. I chose 10, WordPress generally uses 20; Choose what looks best for your content.

‘option’ should be a unique name for your specific option. It will be used to save and retrieve the setting from the database, so you don’t want it to conflict with any other option names.

Example Code

function cmi_add_option() {

$option = 'per_page';

$args = array(
    'label' => 'Movies',
    'default' => 10,
    'option' => 'cmi_movies_per_page'
);

add_screen_option( $option, $args );

}

Step 3: Making Sure WordPress Saves the Setting

At this point, you could navigate to your plugin page, and you should see the screen options tab. If you open the tab, you should see the option we just created, but unfortunately, you could enter values and click apply all day long, and WordPress would not save it for us. This is because WordPress has a list of specific options it will save the value for. If an option doesn’t match, it just gets ignored.

Add a Filter to Save Our Option

Lucky for us, WordPress uses the ‘set-screen-option’ filter when it is processing the screen options, so all we have to do is hook a custom function into this filter.

add_filter('set-screen-option', 'cmi_set_option', 10, 3);

function cmi_set_option($status, $option, $value) {

    if ( 'cmi_movies_per_page' == $option ) return $value;

    return $status;

}

The first line tells WordPress to call the ‘cmi_set_option’ function when it is applying the ‘set-screen-options’ filters, with a (default) priority of 10, and that our function will expect 3 parameters to be passed to it (the default is only 1 for add_filter).

The function cmi_set_option checks if the option that WordPress is processing is our ‘cmi_movies_per_page’ option. If it is our option, we return the value so that WordPress will save it to the database.

Step 4: Retrieving Values of Screen Options

Now that we have WordPress set up to output our custom option and save it to the database, we just need a way to access the value set by the user. When WordPress saves the option to the database, it uses the update_user_meta function, so to retrieve the value that was saved, we will use the get_user_meta function. This function expects us to provide at minimum two parameters (the user id and the option name).

Get the Current WordPress User

$user = get_current_user_id();
<span style="font-family: 'Courier 10 Pitch', Courier, monospace; font-size: x-small"><span style="line-height: 19px;">

To get the user id, we will utilize the get_current_user_id function. The above code gets the user id for the user that is viewing the current page, and saves it to the $user variable.

Get The Name Of Our Option

$screen = get_current_screen();
$option = $screen->get_option('per_page', 'option');

The first thing we are doing here is setting the $screen variable to the current screen object by calling get_current_screen. Once we have the screen object, it has several methods that can be called to get information about the specific page we are on, including information we defined earlier about our custom option.
One of the methods available is the get_option method, which requires at least one parameter, the option name. In the example code for step 2, we set $option to ‘per_page’, so that is the option name we will want to pass as the first parameter. The second parameter is optional, and can be used to get a specific argument that was set in the $args array of add_screen_option. Since we want the name of our option, we pass ‘option’ here, but if we wanted the default value, we could pass ‘default’. Similarly, if we wanted the label, we could pass ‘label’ as the second parameter.
If you were to omit the second parameter completely, an array of all the option arguments would be returned.

Get The Value Of Our Setting

$per_page = get_user_meta($user, $option, true);

Now all we have to do is supply the get_user_meta function with the values we now have stored in variables. The third argument in the function tells it to return a single value. If we were to omit the ‘true’, an array would be returned instead.

 Step 5: Verify the Setting Value

If you were to try and echo the value of $per_page, unless you have already set a value with the custom option, nothing would show up on the screen. To fix this issue, we can check if a value was returned for the user. While we’re at it, we can check if the value is acceptable to us.

if ( empty ( $per_page ) || $per_page < 1 ) {

    $per_page = $screen->get_option( 'per_page', 'default' );

}

Here, we are first checking if the variable $per_page is an empty value. If it is not empty, we then check if the value is less than 1. If either the variable is empty or the value is less than one, we are using the get_option method of the $screen object to get the default value we assigned when we set up the option.

Conclusion

Now you know how to add an option to set the number of items per page to the Screen Options tab. That’s one less option to clutter up your plugin’s settings page. The complete code from this tutorial is split into two sections below.

Setting up and making sure the option is saved:

$hook = add_menu_page( $pg_title, $menu_title, $cap, $slug, $function );

add_action( "load-$hook", 'cmi_add_option' );

function cmi_add_option() {

    $option = 'per_page';

    $args = array(
        'label' => 'Movies',
        'default' => 10,
        'option' => 'cmi_movies_per_page'
    );

    add_screen_option( $option, $args );

}

add_filter('set-screen-option', 'cmi_set_option', 10, 3);

function cmi_set_option($status, $option, $value) {

    if ( 'cmi_movies_per_page' == $option ) return $value;

    return $status;

}

Retrieving and validating values of screen options

$user = get_current_user_id();
$screen = get_current_screen();
$option = $screen->get_option('per_page', 'option');

$per_page = get_user_meta($user, $option, true);

if ( empty ( $per_page) || $per_page < 1 ) {

    $per_page = $screen->get_option( 'per_page', 'default' );

}

One thought on “How To Use Screen Options in your WordPress Plugin

  1. Thanks for the how to, this just save me several hours of hunting through code to figure this out.

  2. I’d suggest on your wordpress-screen-options-tutorial post that you prevent conflicts with other plugins by only adding the filter ‘set-screen-option’ if you know you are on your plugin’s page:

    if ( ! empty( $_GET[ ‘page’ ] ) && $menu_slug === $_GET[ ‘page’ ] ) {
    add_filter(‘set-screen-option’, ‘cmi_set_option’, 10, 3);
    }

    I have a full working sample plugin which documents the crazy WP hooks, search “custom-list-table-screen-options-example” at Github.

    It relies on the the “custom-list-table-example” plugin in the WP repo. That plugin uses the WP_List_Table class in WP, but I think it’s a better idea to copy a frozen version of the class, rename it, and put it your plugin. Still doesn’t prevent changes in WP from affecting style and scripts, so maybe not worth it. A few years ago the WP devs were still insisting the class is @private. Maybe they will change their minds now that they are adding features to it for 4.3.

Comments are closed.