• About Us
    • New York
  • Work
  • Capabilities
  • Careers
  • Technology
  • Blog
  • Contact Us
  • About Us
    • New York
  • Work
  • Capabilities
  • Careers
  • Technology
  • Blog
  • Contact Us
June 11, 2012

Adding WordPress Screen Options

Posted by Christopher Davis

WordPress has built in support for things called screen options. If you take a look at the top of the post editing screen, for instance, you’ll see two tabs. One for help and one for the screen options.

WordPress Screen Options

This tutorial will cover adding your own screen options. We’re going to give our users the option of change the default “Enter Title Here” text on new posts.

The Deceptive add_screen_option

The WP_Screen class has a method called add_option. There’s also a wrapper function for that called add_screen_option. Both of these are deceptive: they appear to add support automatically – maybe you can specify a callback function to render your fields and titles and such?

That’s not the case. add_screen_option only works for a set of predefined screen options (like per_page). Adding any custom options takes a bit more work.

Adding the Field

To add our field, we’ll need to hook into screen_settings. Before we do that, let’s setup a container class to hold all of our functionality. There are a few class constants in here, we’ll use later on.


class PMG_Options_Tut

{

/**

* The ajax action

*/

const ACTION = ‘pmg_sotut_save’;

/**

* Our nonce name

*/

const NONCE = ‘pmg_sotut_nonce’;

public static function init()

{

// we’ll add actions here

}

} // end class

PMG_Options_Tut::init();

Unfortunately, screen_settings fires on every admin page. So we need to figure out a way to fire our hook only the post-new.php page where it matters. To do that, we’ll hook into load-post-new.php and from there we can add filters as needed.


public static function init()

{

add_action(

‘load-post-new.php’,

array(get_class(), ‘load’)

);

}

And of course, our load method. There are several other filters/actions added in here that we’ll cover later on.


/**

* Hooked into ‘load-post-new.php’. Adds an option and

* hooks into a few other actions/filters

*

* @access public

* @return null

*/

public static function load()

{

add_filter(

‘screen_settings’,

array(get_class(), ‘add_field’),

10,

2

);

add_action(

‘admin_head’,

array(get_class(), ‘head’)

);

add_filter(

‘enter_title_here’,

array(get_class(), ‘title’)

);

}

The function hooked into screen_settings will get two arguments, the return value (a string with other custom fields, etc) and the current WP_Screen object.


<?php

/**

* Hooked into ‘screen_settings’. Adds the field to the settings area

*

* @access public

* @return string The settings fields

*/

public static function add_field($rv, $screen)

{

$val = get_user_option(

sprintf(‘default_title_%s’, sanitize_key($screen->id)),

get_current_user_id()

);

$rv .= ‘<div class=”pmg-sotut-container”>’;

$rv .= ‘<h5>’ . __(‘Default Title’) . ‘</h5>’;

$rv .= ‘<p><input type=”text” class=”normal-text” id=”pmg-sotut-field” ‘ .

‘value=”‘ . esc_attr($val) . ‘” /></p>’;

$rv .= wp_nonce_field(self::NONCE, self::NONCE, false, false);

$rv .= ‘</div>’;

return $rv;

}

There’s a lot of stuff going on in this method, so let’s break it down. First, we’ll get the current users setting for default_title_{$screen->id} with get_user_option. Next we build our field and add a nonce that we’ll use in ajax calls. Finally we just return the initial string with our field appended.

That wraps up actually getting the field to display. Now let’s save the data!

Saving Custom Screen Options

WordPress saves things like meta box display and other screen options via Ajax calls. Which means, of course, that we need to write our own AJAX methods. Step one, of course, is actually getting an AJAX request to fire when our custom field loses focus. So we’ll hook into admin_head – you can see that in the load method above – and spit out some JavaScript:


<?php

/**

* Hooked into ‘admin_head’. Spits out some JS to save the info

*

* @access public

* @return null

*/

public static function head()

{

?>

<script type=”text/javascript”>

jQuery(document).ready(function() {

jQuery(‘input#pmg-sotut-field’).blur(function() {

jQuery.post(

ajaxurl,

{

title: jQuery(this).val(),

nonce: jQuery(‘input#<?php echo esc_js(self::NONCE); ?>’).val(),

screen: ‘<?php echo esc_js(get_current_screen()->id); ?>’,

action: ‘<?php echo self::ACTION; ?>’

}

);

});

});

</script>

<?php

}

The jQuery above just makes an ajax request with the title we want, the nonce, and the current screen id. The server side portion of this is that we need to hook into wp_ajax_{$action} and handle saving everything. Let’s modify our init function to include that hook.


/**

* Init function. Called from outside the class. Adds actions and such.

*

* @access public

* @return null

*/

public static function init()

{

add_action(

‘load-post-new.php’,

array(get_class(), ‘load’)

);

add_action(

‘wp_ajax_’ . self::ACTION,

array(get_class(), ‘ajax’)

);

}

And the function that handles ajax request:


/**

* Hooked into ‘wp_ajax_self::ACTION’  Handles saving the fields and such

*

* @access public

* @return null

*/

public static function ajax()

{

check_ajax_referer(self::NONCE, ‘nonce’);

$screen = isset($_POST[‘screen’]) ? $_POST[‘screen’] : false;

$title = isset($_POST[‘title’]) ? $_POST[‘title’] : false;

if(!$screen || !($user = wp_get_current_user()))

{

die(0);

}

if(!$screen = sanitize_key($screen))

{

die(0);

}

update_user_option(

$user->ID,

“default_title_{$screen}”,

esc_attr(strip_tags($title))

);

die(‘1’);

}

First this checks to make sure our nonce validates and that we have the $screen variable we need. It also fetches the current, logged in user. Finally a call to update_user_option saves the title.

Changing the Title

The final bit of all this is hooking into enter_title_here and replace the value with the users text.


/**

* Hooked into ‘enter_title_here’. Replaces the title with the user’s

* preference (if it exists).

*

* @access public

* @return string The Default title

*/

public static function title($t)

{

if(!$user = wp_get_current_user())

return $t;

$id = sanitize_key(get_current_screen()->id);

if($title = get_user_option(“default_title_{$id}”, $user->ID))

{

$t = esc_attr($title);

}

return $t;

}

That thats it!  After updating the option, the next view of post-new.php should use the new default. You can see all this code together on github.

devDevelopmentwordpresswordpress screen
Previous
Next

Latest White Papers

  • Shifting Plans for 2020 & Beyond
  • Game On: How Brands Can Log Into A Diverse Multi-Billion Dollar Industry
  • What CCPA Means For Brands
  • How Google is Improving Consumer Data Privacy
  • Ways to Prepare for the Cookieless Future
  • See all White Papers

Featured Posts

  • Ad Age Names PMG #1 Best Place to Work in 2021
  • MediaPost Names PMG Independent Agency of the Year
  • PMG Client Portfolio Trends During Amazon Prime Day 2020
  • A Closer Look at the Congressional Big Tech Market Power Report
  • What to Know About Reddit

Categories

  • Consumer Insights
  • Content
  • Creative Design
  • Data Analytics
  • Development
  • Digital TV & Video
  • Ecommerce
  • Industry News
  • Local
  • Mobile
  • Paid Search
  • PMG Culture
  • Programmatic & Display
  • SEO
  • Social Media
  • Structured Data
Fort Worth

2845 West 7th Street
Fort Worth, TX 76107

Dallas

3102 Oak Lawn Avenue
Suite 650
Dallas, TX 75219

Austin

823 Congress Avenue
Suite 800
Austin, TX 78701

London

33 Broadwick Street
London
W1F 0DQ

New York

120 East 23rd Street
New York, NY 10010

Get in touch

(817) 420 9970
info@pmg.com

Subscribe to the PMG Newsletter
© 2021 PMG Worldwide, LLC, All Rights Reserved
  • Contact
  • Privacy Policy
 Tweet
 Share
 Tweet
 Share
 Tweet
 Share
 LinkedIn
We and our partners use cookies to personalize content, analyze traffic, and deliver ads. By using our website, you agree to the use of cookies as described in our Cookie Policy.