Skip to content

Instantly share code, notes, and snippets.

@chrisguitarguy
Created December 2, 2012 05:49
Show Gist options
  • Save chrisguitarguy/4187138 to your computer and use it in GitHub Desktop.
Save chrisguitarguy/4187138 to your computer and use it in GitHub Desktop.
Settings API + Tabs. Not bad. More complicated than it needs to be?
<?php
/**
* Plugin Name: Settings API + Tabs
* Plugin URI: http://christopherdavis.me
* Description: Turn settings sections into tabs on an options page. A simple example.
* Version: 0.1
* Text Domain: settings-tabs
* Author: Christopher Davis
* Author URI: http://christopherdavis.me
* License: MIT
*
* Copyright (c) 2012 Christopher Davis <http://christopherdavis.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* @category WordPress
* @author Christopher Davis <http://christopherdavis.me>
* @copyright 2012 Christopher Davis
* @license http://opensource.org/licenses/MIT MIT
*/
!defined('ABSPATH') && exit;
Settings_Tabs_Tut::init();
class Settings_Tabs_Tut
{
/**
* The settings we'll use.
*
* @since 0.1
*/
const PAGE = 'settings_tabs_tut';
/**
* container for the instance of this class.
*
* @since 0.1
* @access private
* @var Settings_Tab_Tut
* @static
*/
private static $ins = null;
/**
* Get the instance of this class.
*
* @since 0.1
* @access public
* @return void
* @static
*/
public static function instance()
{
is_null(self::$ins) && self::$ins = new self;
return self::$ins;
}
/**
* Kick everything off. At the `_setup` method to the `plugins_loaded`
* hook.
*
* @since 0.1
* @access public
* @uses add_action
* @return void
* @static
*/
public static function init()
{
add_action('plugins_loaded', array(self::instance(), '_setup'));
}
/**
* Adds and actions and such.
*
* @since 0.1
* @access public
* @uses add_action
* @uses add_filter
* @return void
*/
public function _setup()
{
add_action('admin_menu', array($this, 'page'));
add_filter('whitelist_options', array($this, 'change_whitelist'), 11);
add_action('admin_init', array($this, 'register'));
}
/**
* Adds a new admin page.
*
* @since 0.1
* @access public
* @uses add_options_page
* @return void
*/
public function page()
{
$p = add_options_page(
__('Settings Tabs', 'settings-tabs'),
__('Settings Tabs', 'settings-tabs'),
'manage_options',
'settings-tabs-tut',
array($this, 'page_cb')
);
}
/**
* Alter the whitelist options on the `options.php` admin page so we
* don't loose changes to settings due to the fields not beeing there.
*
* @since 0.1
* @access public
* @param array $opts A multi-dimensional array of options.
* @return void
*/
public function change_whitelist($opts)
{
if(empty($_POST) || $_POST['action'] != 'update')
return $opts;
// since WP tries to update ALL settings assigned to a particular page.
// We want to make sure that we unset the other settings that aren't
// on the current request so they don't get overwritten.
// this is going to have to be on a case by case basis --
// sections aren't added with a knowledge of the setting to which
// they belong. One section per setting makes it easy!
$sect = isset($_POST['current_section']) ? $_POST['current_section'] : 'default';
$s = 'default' == $sect ? 'settings_tab_test_two' : 'settings_tab_test';
if(($pos = array_search($s, $opts[self::PAGE])) !== false)
{
unset($opts[self::PAGE][$pos]);
}
return $opts;
}
/**
* Registers settings, sections and fields.
*
* @since 0.1
* @access public
* @uses register_setting
* @uses add_settings_section
* @uses add_settings_field
* @return void
*/
public function register()
{
// so we can sections and they'll show up as tabs.
register_setting(
self::PAGE,
'settings_tab_test'
);
add_settings_section(
'default',
__('Settings Tut', 'settings-tabs'),
'__return_false',
self::PAGE
);
add_settings_field(
'some-field',
__('Some Field', 'settings-tabs'),
array($this, 'field_cb'),
self::PAGE,
'default',
array('setting' => 'settings_tab_test')
);
// another one just for fun.
register_setting(
self::PAGE,
'settings_tab_test_two'
);
add_settings_section(
'again',
__('Another Tab', 'settings-tabs'),
'__return_false',
self::PAGE
);
add_settings_field(
'another-field',
__('Another Field', 'settings-tabs'),
array($this, 'field_cb'),
self::PAGE,
'again',
array('setting' => 'settings_tab_test_two')
);
}
/**
* Callback for the page.
*
* @since 0.1
* @access public
* @return void
*/
public function page_cb()
{
global $wp_settings_sections;
// current section.
$sect = isset($_GET['tab']) ? $_GET['tab'] : 'default';
// sections on this page.
$sections = $this->get_sections();
// url of this page.
$url = add_query_arg(
'page', 'settings-tabs-tut', admin_url('options-general.php'));
?>
<div class="wrap">
<?php screen_icon(); ?>
<?php if($sections): ?>
<h2 class="nav-tab-wrapper">
<?php foreach($sections as $id => $data): ?>
<a class="nav-tab <?php echo ($sect == $id ? 'nav-tab-active' : ''); ?>"
href="<?php echo add_query_arg('tab', $id, $url); ?>"><?php echo esc_html($data['title']); ?></a>
<?php endforeach; ?>
</h2>
<?php else: ?>
<h2><?php esc_html_e('Settings Tab Tut', 'settings-tabs'); ?></h2>
<?php endif; ?>
<?php settings_errors(self::PAGE); ?>
<?php
if(isset($sections[$sect]['callback']))
{
call_user_func($sections[$sect]['callback']);
}
?>
<form method="post" action="<?php echo admin_url('options.php'); ?>">
<input type="hidden" name="current_section" value="<?php echo esc_attr($sect); ?>" />
<table class="form-table">
<?php
settings_fields(self::PAGE);
do_settings_fields(self::PAGE, $sect);
?>
</table>
<p><?php submit_button(__('Save Settings', 'settings-tabs')); ?></p>
</form>
</div>
<?php
}
/**
* callback for our example fields.
*
* @since 0.1
* @access public
* @return void
*/
public function field_cb($args)
{
$opt = get_option($args['setting']);
printf(
'<input type="text" name="%1$s" id="%1$s" value="%2$s" class="widefat" />',
esc_attr($args['setting']),
esc_attr($opt)
);
}
/**
* Get all the sections for the page.
*
* @since 0.1
* @access private
* @return array
*/
private function get_sections()
{
global $wp_settings_sections;
return isset($wp_settings_sections[self::PAGE]) ?
$wp_settings_sections[self::PAGE] : array();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment