Skip to main content
change &$this to $this
Source Link
kitchin
  • 271
  • 2
  • 7
  • My example demonstrates both simple options (de_w, de_h) and an array option (de_width_height).
  • Always sanitize user input. I used integers in the example because they are easy to sanitize.
  • You do not need $_POST, nonces, check_admin_referer(), update_option(), etc., when using the Settings API.
  • The save happens on the next page load, not at shutdown. Then WP does a redirect to your page. So to debug, print some output and call wp_die() in one of the validation functions.
  • The form action is always "options.php." That is how the Settings API works. Do not use anything else. Well, you can use admin_url('options.php') if you want.
  • WP will print the save message for you.
  • Enhancements not included here: using <label> for accessibility. Using add_settings_error(), settings_error(), which handle messages as well as errors. That's often the only reason to have separate validation functions for each option. You can see below validate_w() and validate_h() could be one function. I looked at trying to abstract out the messaging, but you don't get enough info in the validation callback as I recall. Like what field you're working on.
  • The validation callback functions get a raw $_POST value from the Settings API. I like to name the parameter as such, $raw. For the array option, you get an array, like magic.
  • Edit: $this is better than &$this.
<?php
$foo= new de_Foo();
class de_Foo {
function __construct() {
    if (is_admin()) {
        add_action('admin_menu', array(&$this$this, 'admin_menu'));
        add_action('admin_init', array(&$this$this, 'admin_init'));
    } 
}
public function admin_menu() {
    add_options_page(
       'DE Menu Options',
       'DE Menu',
       'manage_options',
       'de-menu-options',
       array(&$this$this,'xoxptions')
    );
    // add_option('de-menu-options', $this->options);
}
public function admin_init() {
 register_setting(
      'de-menu-settings-group',
      'de_w',
      array(&$this$this, 'validate_w')
 );
 register_setting(
      'de-menu-settings-group',
      'de_h',
      array(&$this$this, 'validate_h')
 );
 register_setting(
      'de-menu-settings-group',
      'de_width_height',
      array(&$this$this, 'validate_width_height')
 );
 add_settings_section(
      'de-menu-settings-section-size',
      'Size',
      array(&$this$this, 'settings_section_size_render'),
      'de-menu-options'
 );
 add_settings_field(
      'de_w',
      'W',
      array(&$this$this, 'w_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
 add_settings_field(
      'de_h',
      'H',
      array(&$this$this, 'h_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
 add_settings_field(
      'de_width_height',
      'Width / Height',
      array(&$this$this, 'width_height_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
}
public function options() {
    if (!current_user_can('manage_options')) {
        wp_die( __('You do not have sufficient permissions to access this page.') );
    }
////////////////////////////
// no no no
////////////////////////////
//         if ( !empty($_POST) && check_admin_referer('de-menu-options') ) {
//             // These options are saved to the database at shutdown
//             $this->options = array(
//                 "columns" => $_POST["de-menu-columns"],
//                 "maintenance" => $_POST["de-menu-maintenance"]
//             );
//             echo 'DE Menu options saved';
//         }
////////////////////////////
?>
<div class="wrap">
<h2>DE Menu Plugin</h2>
<form method="post" action="<?php echo admin_url('options.php'); ?>">
    <?php settings_fields('de-menu-settings-group'); ?>
    <?php do_settings_sections('de-menu-options'); ?>
    <p class="submit">
    <input type="submit" name="de-menu-submit" value="Update Options" />
    </p>
</form>
</div>
<?php
}
public function settings_section_size_render() {
    echo '<p>' . __('Main description of this section here.','de-menu-lang') . '</p>';
}
public function w_render() {
 $w= esc_attr( get_option('de_w') );
 echo "<p><input name='de_w' value='$w'></p>\n";
}
public function h_render() {
 $h= esc_attr( get_option('de_h') );
 echo "<p><input name='de_h' value='$h'></p>\n";
}
public function width_height_render() {
 $width_height= get_option('de_width_height', array());
 $width= esc_attr( @$width_height['width'] );
 $height= esc_attr( @$width_height['height'] );
 echo "<p>Width: <input name='de_width_height[width]' value='$width'></p>\n";
 echo "<p>Height: <input name='de_width_height[height]' value='$height'></p>\n";
}
function validate_w($raw) {
 return (int)$raw;
}
function validate_h($raw) {
 return (int)$raw;
}
function validate_width_height($raw) {
 is_array($raw) or $raw= array();
 $result= array();
 $result['width']= (int)@$raw['width'];
 $result['height']= (int)@$raw['height'];
 return $result;
}
}
  • My example demonstrates both simple options (de_w, de_h) and an array option (de_width_height).
  • Always sanitize user input. I used integers in the example because they are easy to sanitize.
  • You do not need $_POST, nonces, check_admin_referer(), update_option(), etc., when using the Settings API.
  • The save happens on the next page load, not at shutdown. Then WP does a redirect to your page. So to debug, print some output and call wp_die() in one of the validation functions.
  • The form action is always "options.php." That is how the Settings API works. Do not use anything else. Well, you can use admin_url('options.php') if you want.
  • WP will print the save message for you.
  • Enhancements not included here: using <label> for accessibility. Using add_settings_error(), settings_error(), which handle messages as well as errors. That's often the only reason to have separate validation functions for each option. You can see below validate_w() and validate_h() could be one function. I looked at trying to abstract out the messaging, but you don't get enough info in the validation callback as I recall. Like what field you're working on.
  • The validation callback functions get a raw $_POST value from the Settings API. I like to name the parameter as such, $raw. For the array option, you get an array, like magic.
<?php
$foo= new de_Foo();
class de_Foo {
function __construct() {
    if (is_admin()) {
        add_action('admin_menu', array(&$this, 'admin_menu'));
        add_action('admin_init', array(&$this, 'admin_init'));
    } 
}
public function admin_menu() {
    add_options_page(
       'DE Menu Options',
       'DE Menu',
       'manage_options',
       'de-menu-options',
       array(&$this,'xoxptions')
    );
    // add_option('de-menu-options', $this->options);
}
public function admin_init() {
 register_setting(
      'de-menu-settings-group',
      'de_w',
      array(&$this, 'validate_w')
 );
 register_setting(
      'de-menu-settings-group',
      'de_h',
      array(&$this, 'validate_h')
 );
 register_setting(
      'de-menu-settings-group',
      'de_width_height',
      array(&$this, 'validate_width_height')
 );
 add_settings_section(
      'de-menu-settings-section-size',
      'Size',
      array(&$this, 'settings_section_size_render'),
      'de-menu-options'
 );
 add_settings_field(
      'de_w',
      'W',
      array(&$this, 'w_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
 add_settings_field(
      'de_h',
      'H',
      array(&$this, 'h_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
 add_settings_field(
      'de_width_height',
      'Width / Height',
      array(&$this, 'width_height_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
}
public function options() {
    if (!current_user_can('manage_options')) {
        wp_die( __('You do not have sufficient permissions to access this page.') );
    }
////////////////////////////
// no no no
////////////////////////////
//         if ( !empty($_POST) && check_admin_referer('de-menu-options') ) {
//             // These options are saved to the database at shutdown
//             $this->options = array(
//                 "columns" => $_POST["de-menu-columns"],
//                 "maintenance" => $_POST["de-menu-maintenance"]
//             );
//             echo 'DE Menu options saved';
//         }
////////////////////////////
?>
<div class="wrap">
<h2>DE Menu Plugin</h2>
<form method="post" action="<?php echo admin_url('options.php'); ?>">
    <?php settings_fields('de-menu-settings-group'); ?>
    <?php do_settings_sections('de-menu-options'); ?>
    <p class="submit">
    <input type="submit" name="de-menu-submit" value="Update Options" />
    </p>
</form>
</div>
<?php
}
public function settings_section_size_render() {
    echo '<p>' . __('Main description of this section here.','de-menu-lang') . '</p>';
}
public function w_render() {
 $w= esc_attr( get_option('de_w') );
 echo "<p><input name='de_w' value='$w'></p>\n";
}
public function h_render() {
 $h= esc_attr( get_option('de_h') );
 echo "<p><input name='de_h' value='$h'></p>\n";
}
public function width_height_render() {
 $width_height= get_option('de_width_height', array());
 $width= esc_attr( @$width_height['width'] );
 $height= esc_attr( @$width_height['height'] );
 echo "<p>Width: <input name='de_width_height[width]' value='$width'></p>\n";
 echo "<p>Height: <input name='de_width_height[height]' value='$height'></p>\n";
}
function validate_w($raw) {
 return (int)$raw;
}
function validate_h($raw) {
 return (int)$raw;
}
function validate_width_height($raw) {
 is_array($raw) or $raw= array();
 $result= array();
 $result['width']= (int)@$raw['width'];
 $result['height']= (int)@$raw['height'];
 return $result;
}
}
  • My example demonstrates both simple options (de_w, de_h) and an array option (de_width_height).
  • Always sanitize user input. I used integers in the example because they are easy to sanitize.
  • You do not need $_POST, nonces, check_admin_referer(), update_option(), etc., when using the Settings API.
  • The save happens on the next page load, not at shutdown. Then WP does a redirect to your page. So to debug, print some output and call wp_die() in one of the validation functions.
  • The form action is always "options.php." That is how the Settings API works. Do not use anything else. Well, you can use admin_url('options.php') if you want.
  • WP will print the save message for you.
  • Enhancements not included here: using <label> for accessibility. Using add_settings_error(), settings_error(), which handle messages as well as errors. That's often the only reason to have separate validation functions for each option. You can see below validate_w() and validate_h() could be one function. I looked at trying to abstract out the messaging, but you don't get enough info in the validation callback as I recall. Like what field you're working on.
  • The validation callback functions get a raw $_POST value from the Settings API. I like to name the parameter as such, $raw. For the array option, you get an array, like magic.
  • Edit: $this is better than &$this.
<?php
$foo= new de_Foo();
class de_Foo {
function __construct() {
    if (is_admin()) {
        add_action('admin_menu', array($this, 'admin_menu'));
        add_action('admin_init', array($this, 'admin_init'));
    } 
}
public function admin_menu() {
    add_options_page(
       'DE Menu Options',
       'DE Menu',
       'manage_options',
       'de-menu-options',
       array($this,'xoxptions')
    );
    // add_option('de-menu-options', $this->options);
}
public function admin_init() {
 register_setting(
      'de-menu-settings-group',
      'de_w',
      array($this, 'validate_w')
 );
 register_setting(
      'de-menu-settings-group',
      'de_h',
      array($this, 'validate_h')
 );
 register_setting(
      'de-menu-settings-group',
      'de_width_height',
      array($this, 'validate_width_height')
 );
 add_settings_section(
      'de-menu-settings-section-size',
      'Size',
      array($this, 'settings_section_size_render'),
      'de-menu-options'
 );
 add_settings_field(
      'de_w',
      'W',
      array($this, 'w_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
 add_settings_field(
      'de_h',
      'H',
      array($this, 'h_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
 add_settings_field(
      'de_width_height',
      'Width / Height',
      array($this, 'width_height_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
}
public function options() {
    if (!current_user_can('manage_options')) {
        wp_die( __('You do not have sufficient permissions to access this page.') );
    }
////////////////////////////
// no no no
////////////////////////////
//         if ( !empty($_POST) && check_admin_referer('de-menu-options') ) {
//             // These options are saved to the database at shutdown
//             $this->options = array(
//                 "columns" => $_POST["de-menu-columns"],
//                 "maintenance" => $_POST["de-menu-maintenance"]
//             );
//             echo 'DE Menu options saved';
//         }
////////////////////////////
?>
<div class="wrap">
<h2>DE Menu Plugin</h2>
<form method="post" action="<?php echo admin_url('options.php'); ?>">
    <?php settings_fields('de-menu-settings-group'); ?>
    <?php do_settings_sections('de-menu-options'); ?>
    <p class="submit">
    <input type="submit" name="de-menu-submit" value="Update Options" />
    </p>
</form>
</div>
<?php
}
public function settings_section_size_render() {
    echo '<p>' . __('Main description of this section here.','de-menu-lang') . '</p>';
}
public function w_render() {
 $w= esc_attr( get_option('de_w') );
 echo "<p><input name='de_w' value='$w'></p>\n";
}
public function h_render() {
 $h= esc_attr( get_option('de_h') );
 echo "<p><input name='de_h' value='$h'></p>\n";
}
public function width_height_render() {
 $width_height= get_option('de_width_height', array());
 $width= esc_attr( @$width_height['width'] );
 $height= esc_attr( @$width_height['height'] );
 echo "<p>Width: <input name='de_width_height[width]' value='$width'></p>\n";
 echo "<p>Height: <input name='de_width_height[height]' value='$height'></p>\n";
}
function validate_w($raw) {
 return (int)$raw;
}
function validate_h($raw) {
 return (int)$raw;
}
function validate_width_height($raw) {
 is_array($raw) or $raw= array();
 $result= array();
 $result['width']= (int)@$raw['width'];
 $result['height']= (int)@$raw['height'];
 return $result;
}
}
Source Link
kitchin
  • 271
  • 2
  • 7

Thanks for posting this, I was wondering the exact same thing. Lots of functions.

To reduce them you can store your options as arrays. Wordpress serializes the data for you. This saves on code (or functions anyway), but makes worse data. For instance, if you want to sort, hand-edit, export, etc., your tables, they will have these serialized values. On the other hand, your plugin adds fewer entries to the options table and they are easier to clean up.

So here's your code re-done. A few notes:

  • My example demonstrates both simple options (de_w, de_h) and an array option (de_width_height).
  • Always sanitize user input. I used integers in the example because they are easy to sanitize.
  • You do not need $_POST, nonces, check_admin_referer(), update_option(), etc., when using the Settings API.
  • The save happens on the next page load, not at shutdown. Then WP does a redirect to your page. So to debug, print some output and call wp_die() in one of the validation functions.
  • The form action is always "options.php." That is how the Settings API works. Do not use anything else. Well, you can use admin_url('options.php') if you want.
  • WP will print the save message for you.
  • Enhancements not included here: using <label> for accessibility. Using add_settings_error(), settings_error(), which handle messages as well as errors. That's often the only reason to have separate validation functions for each option. You can see below validate_w() and validate_h() could be one function. I looked at trying to abstract out the messaging, but you don't get enough info in the validation callback as I recall. Like what field you're working on.
  • The validation callback functions get a raw $_POST value from the Settings API. I like to name the parameter as such, $raw. For the array option, you get an array, like magic.

Code:

<?php
$foo= new de_Foo();
class de_Foo {
function __construct() {
    if (is_admin()) {
        add_action('admin_menu', array(&$this, 'admin_menu'));
        add_action('admin_init', array(&$this, 'admin_init'));
    } 
}
public function admin_menu() {
    add_options_page(
       'DE Menu Options',
       'DE Menu',
       'manage_options',
       'de-menu-options',
       array(&$this,'xoxptions')
    );
    // add_option('de-menu-options', $this->options);
}
public function admin_init() {
 register_setting(
      'de-menu-settings-group',
      'de_w',
      array(&$this, 'validate_w')
 );
 register_setting(
      'de-menu-settings-group',
      'de_h',
      array(&$this, 'validate_h')
 );
 register_setting(
      'de-menu-settings-group',
      'de_width_height',
      array(&$this, 'validate_width_height')
 );
 add_settings_section(
      'de-menu-settings-section-size',
      'Size',
      array(&$this, 'settings_section_size_render'),
      'de-menu-options'
 );
 add_settings_field(
      'de_w',
      'W',
      array(&$this, 'w_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
 add_settings_field(
      'de_h',
      'H',
      array(&$this, 'h_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
 add_settings_field(
      'de_width_height',
      'Width / Height',
      array(&$this, 'width_height_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
}
public function options() {
    if (!current_user_can('manage_options')) {
        wp_die( __('You do not have sufficient permissions to access this page.') );
    }
////////////////////////////
// no no no
////////////////////////////
//         if ( !empty($_POST) && check_admin_referer('de-menu-options') ) {
//             // These options are saved to the database at shutdown
//             $this->options = array(
//                 "columns" => $_POST["de-menu-columns"],
//                 "maintenance" => $_POST["de-menu-maintenance"]
//             );
//             echo 'DE Menu options saved';
//         }
////////////////////////////
?>
<div class="wrap">
<h2>DE Menu Plugin</h2>
<form method="post" action="<?php echo admin_url('options.php'); ?>">
    <?php settings_fields('de-menu-settings-group'); ?>
    <?php do_settings_sections('de-menu-options'); ?>
    <p class="submit">
    <input type="submit" name="de-menu-submit" value="Update Options" />
    </p>
</form>
</div>
<?php
}
public function settings_section_size_render() {
    echo '<p>' . __('Main description of this section here.','de-menu-lang') . '</p>';
}
public function w_render() {
 $w= esc_attr( get_option('de_w') );
 echo "<p><input name='de_w' value='$w'></p>\n";
}
public function h_render() {
 $h= esc_attr( get_option('de_h') );
 echo "<p><input name='de_h' value='$h'></p>\n";
}
public function width_height_render() {
 $width_height= get_option('de_width_height', array());
 $width= esc_attr( @$width_height['width'] );
 $height= esc_attr( @$width_height['height'] );
 echo "<p>Width: <input name='de_width_height[width]' value='$width'></p>\n";
 echo "<p>Height: <input name='de_width_height[height]' value='$height'></p>\n";
}
function validate_w($raw) {
 return (int)$raw;
}
function validate_h($raw) {
 return (int)$raw;
}
function validate_width_height($raw) {
 is_array($raw) or $raw= array();
 $result= array();
 $result['width']= (int)@$raw['width'];
 $result['height']= (int)@$raw['height'];
 return $result;
}
}