Output 'do_settings_sections()' as tabs, not one under the other

I’m using the Settings API on an admin page and it’s marvelously simple and all that.

public function on_show_page(){

    <div id="admin-bar-button-page" class="wrap admin-bar-button">

        <h2><?php _e('Admin Bar Button Settings', 'djg-admin-bar-button'); ?></h2>

        <form action="options.php" method="post">

            <?php settings_fields('admin_bar_button_group'); ?>
            <?php do_settings_sections('djg_admin_bar_button'); ?>
                <?php submit_button('Save Changes', 'primary', 'submit', false); ?>
                <?php submit_button('Restore Defaults', 'delete', 'delete', false); ?>


However, as far as I can tell there is no way to display my four different sections as tabs (using jQuery UI Tabs), rather than one under the other.

Does anybody know of an out of the box way to do this? Thanks.

Solutions Collecting From Web of "Output 'do_settings_sections()' as tabs, not one under the other"

So because I couldn’t find an out of the box way, I created this. Don’t forget to enqueue the jquery-ui-tabs script –

/** Replace the call to 'do_settings_sections()' with a call to this function */
function do_settings_sections_tabs($page){

    global $wp_settings_sections, $wp_settings_fields;

    if(!isset($wp_settings_sections[$page])) :

    echo '<div id="abb-tabs">';
    echo '<ul>';

    foreach((array)$wp_settings_sections[$page] as $section) :


        printf('<li><a href="#%1$s">%2$s</a></li>',
            $section['id'],     /** %1$s - The ID of the tab */
            $section['title']   /** %2$s - The Title of the section */


    echo '</ul>';

    foreach((array)$wp_settings_sections[$page] as $section) :

        printf('<div id="%1$s">',
            $section['id']      /** %1$s - The ID of the tab */


            call_user_func($section['callback'], $section);

        if(!isset($wp_settings_fields) || !isset($wp_settings_fields[$page]) || !isset($wp_settings_fields[$page][$section['id']]))

        echo '<table class="form-table">';
        do_settings_fields($page, $section['id']);
        echo '</table>';

        echo '</div>';


    echo '</div>';


Here is the CSS for it. You could download and enqueue a style from the jQuery UI website if you wish, but none suited me, so I made this –

.ui-tabs ul.ui-tabs-nav{
    border-bottom: 2px solid #E2E2E2;
    line-height: 31px;
.ui-tabs ul.ui-tabs-nav li{
    border-top: 1px solid transparent;
    border-right: 1px solid transparent;
    border-left: 1px solid transparent;
    border-bottom: none;
    display: inline;
    padding: 8px 20px;
.ui-tabs ul.ui-tabs-nav li.ui-state-active{
    background-color: #F1F1F1;
    border-top: 1px solid #E2E2E2;
    border-right: 1px solid #E2E2E2;
    border-left: 1px solid #E2E2E2;
    border-bottom: none;
.ui-tabs ul.ui-tabs-nav li a{
    color: #6BACD9;
    font-size: 1.3em;
    font-weight: bold;
    text-decoration: none;
.ui-tabs ul.ui-tabs-nav li a:hover{
    color: #4A89BF;
.ui-tabs ul.ui-tabs-nav li.ui-state-active a{
    color: #222222;
    cursor: default;

And one simple jQuery function –


The MarkUp to produce tabs in the admin UI is the following:

<h2 class="nav-tab-wrapper">
    <a href="#" class="nav-tab">Tab #1</a>
    <a href="#" class="nav-tab nav-tab-active">Tab #2</a>
    <a href="#" class="nav-tab">Tab #3</a>

Now, when you are requesting an admin page, you can use any query args:


If you register your admin menu page, you simply add a query arg of ?tab=1 directly to the nav menu link. In your UI callback, you then use admin_url() (escaped):

$link = esc_url( admin_url( 'tabshow' ) );

You could as well use $_SERVER['REQUEST_URI'] to simply refer to the same page. On top of that, you just add the query args for tab=1, tab=2, tab=n. You get the point.

Then just switch through the different contents

switch ( $_GET['tab'] )
    default :
    case '1' :
        // contents of page 1
    case '2' :
        // contents of page 2
    case 'n' :
        // contents of page 'n'