How To Create Tabs On WordPress Settings Pages
Using tabs in a user interface can help you better organize content, so it’s only natural that WordPress themes that have a lot of options would benefit from tabs on their settings page. In this tutorial, you will learn how to create a tabbed settings page, and you’ll get to download a WordPress theme that implements the code.
Overview
To get a quick grasp of the tabs we’ll be creating, go to Appearance/Themes in the WordPress admin area. You will find two tabs there: “Manage Themes” and “Install Themes.” When you click on one, the content changes and the tab’s title is highlighted.
The process is actually fairly simple: we set and send a tab variable when a tab is clicked. By querying this tab variable later, in $_GET['tab'], we will know which tab was selected so that we can highlight the corresponding title and display the corresponding tab.
In our approach, there are three times when we will need to know which tab the user is currently on:
- When we initially display the tabs and the form fields for the settings (in order to display the correct set of fields);
- When the user saves their settings (in order to save the correct fields);
- When redirecting the user after they have saved their settings (in order to redirect the user to the correct tab).
For the sake of brevity, we won’t explain all of the code, only the snippets that are relevant to this approach. You can, however, find all of the code in the accompanying theme.
Creating The Tabs
The first snippet we will inspect is the code that produces the tabs:
function ilc_admin_tabs( $current = 'homepage' ) {
$tabs = array( 'homepage' => 'Home Settings', 'general' => 'General', 'footer' => 'Footer' );
echo '<div id="icon-themes" class="icon32"><br></div>';
echo '<h2 class="nav-tab-wrapper">';
foreach( $tabs as $tab => $name ){
$class = ( $tab == $current ) ? ' nav-tab-active' : '';
echo "<a class='nav-tab$class' href='?page=theme-settings&tab=$tab'>$name</a>";
}
echo '</h2>';
}
This function will be called later in the content for the settings page. We first define an array that contains all of our tabs. The first tab, which is displayed first by default, is homepage, where we can set up some option for the appearance of the home page. Then we have general, which could be a page containing options used throughout the website, and, finally, footer, to include a tracking code in the footer.
We then set up the URL links for each tab and output them. Notice that if the tab is open, an additional class, nav-tab-active, is added.
Displaying The Tabbed Content
The content for the settings page is displayed in the callback function for add_theme_page (which is an abstraction of add_submenu_page, with the parent slug set to themes.php), which in our theme will be named ilc_settings_page. This is where you will call the function that we just went over.
function ilc_settings_page() {
global $pagenow;
$settings = get_option( "ilc_theme_settings" );
//generic HTML and code goes here
if ( isset ( $_GET['tab'] ) ) ilc_admin_tabs($_GET['tab']); else ilc_admin_tabs('homepage');
If the tab is the default one, then $_GET['tab'] is not defined, in which case the current tab will be homepage and, thus, the highlighted one. Otherwise, the highlighted tab will be the one defined in $_GET['tab'].
Following the same function, we now need to display the right set of fields. Depending on the value of $tab, we would display the fields for the settings tab for the home page or for one of the other tabs:
<form method="post" action="<?php admin_url( 'themes.php?page=theme-settings' ); ?>">
<?php
wp_nonce_field( "ilc-settings-page" );
if ( $pagenow == 'themes.php' && $_GET['page'] == 'theme-settings' ){
if ( isset ( $_GET['tab'] ) ) $tab = $_GET['tab'];
else $tab = 'homepage';
echo '<table class="form-table">';
switch ( $tab ){
case 'general' :
?>
<tr>
<th>Tags with CSS classes:</th>
<td>
<input id="ilc_tag_class" name="ilc_tag_class" type="checkbox" <?php if ( $settings["ilc_tag_class"] ) echo 'checked="checked"'; ?> value="true" />
<label for="ilc_tag_class">Checking this will output each post tag with a specific CSS class based on its slug.</label>
</td>
</tr>
<?php
break;
case 'footer' :
?>
<tr>
<th><label for="ilc_ga">Insert tracking code:</label></th>
<td>
Enter your Google Analytics tracking code:
<textarea id="ilc_ga" name="ilc_ga" cols="60" rows="5"><?php echo esc_html( stripslashes( $settings["ilc_ga"] ) ); ?></textarea><br />
</td>
</tr>
<?php
break;
case 'homepage' :
?>
<tr>
<th><label for="ilc_intro">Introduction</label></th>
<td>
Enter the introductory text for the home page:
<textarea id="ilc_intro" name="ilc_intro" cols="60" rows="5" ><?php echo esc_html( stripslashes( $settings["ilc_intro"] ) ); ?></textarea>
</td>
</tr>
<?php
break;
}
echo '</table>';
}
?>
<p class="submit" style="clear: both;">
<input type="submit" name="Submit" class="button-primary" value="Update Settings" />
<input type="hidden" name="ilc-settings-submit" value="Y" />
</p>
</form>
All of the settings will be stored in a single array in order to prevent several queries from being made.
Saving The Tabbed Fields
Now we need to know which slots of the array to save. Depending on the tab being displayed, certain options stored in the settings array will be displayed. If we just save all of the array slots, then we would overwrite some of the positions not shown in the current tab and thus not meant to be saved.
function ilc_save_theme_settings() {
global $pagenow;
$settings = get_option( "ilc_theme_settings" );
if ( $pagenow == 'themes.php' && $_GET['page'] == 'theme-settings' ){
if ( isset ( $_GET['tab'] ) )
$tab = $_GET['tab'];
else
$tab = 'homepage';
switch ( $tab ){
case 'general' :
$settings['ilc_tag_class'] = $_POST['ilc_tag_class'];
break;
case 'footer' :
$settings['ilc_ga'] = $_POST['ilc_ga'];
break;
case 'homepage' :
$settings['ilc_intro'] = $_POST['ilc_intro'];
break;
}
}
//code to filter html goes here
$updated = update_option( "ilc_theme_settings", $settings );
}
We’ve used a switch conditional again to query the value of $tab and store the right values in the array. After that, we’ve updated the option in the WordPress database.
Redirecting The User To The Right Tab
Now that the contents are saved, we need WordPress to redirect the user back to the appropriate tab on the settings page.
function ilc_load_settings_page() {
if ( $_POST["ilc-settings-submit"] == 'Y' ) {
check_admin_referer( "ilc-settings-page" );
ilc_save_theme_settings();
$url_parameters = isset($_GET['tab'])? 'updated=true&tab='.$_GET['tab'] : 'updated=true';
wp_redirect(admin_url('themes.php?page=theme-settings&'.$url_parameters));
exit;
}
}
Depending on whether the $_GET['tab'] variable is set, we use wp_redirect to send the user either to the default tab or to one of the other tabs.
Now our tabs are working, displaying the right set of fields, saving the right fields, and then redirecting the user to the correct tab.
Download The Theme
Almost any theme with a moderate number of options would benefit from tabs on the settings page. Just remember that this is one approach. Another approach would be to add several collapsable meta boxes, as seen on the page for writing posts, and to automatically collapse the boxes that are not frequently used. However, tabs enable you to better separate each set of options.
Finally, here is the theme, so that you can take a closer look:
The theme also implements the function whereby each tag is outputted with a unique CSS class, so you can check that out, too.
(al)







kilinkis
October 20th, 2011 10:38 amvery helpful! you rock Elio!
carlos
October 20th, 2011 10:39 amGreaaaaattttt article. Thanks a lot!
I will use this soon..
Galen Gidman
October 20th, 2011 10:42 amThanks for the tutorial. I’ve been seeing a lot of themes and option frameworks take this tabbed approach lately… is it the one WordPress is pushing for?
veerendra
October 20th, 2011 11:22 amhi ..
thanks for details and focus on this section. i have one question . week ago i used jquery ui and tabs script that comes with wp. is this method faster than using inbuilt jquery UI and tabs getting custom tabs as u like? what is difference here ?
Elio Rivero
October 20th, 2011 11:47 amSince these tabs are completely JavaScript agnostic they are very easy on client system resources and also fully compatible with browsers. These tabs use the same approach and styling than WordPress own tabs so by using these tabs you can get a settings page that blends nicely into the overall WP Admin look and feel, if that’s what you’re looking for.
veerendra
October 21st, 2011 12:33 amso if you need some customization or different design then my way is correct !
thanks for the efforts and answer ;)
Alex
October 20th, 2011 11:46 amUseful tutorial. Thank you Elio!
Brad Vincent
October 20th, 2011 11:50 amFor interest sake, a similar great post on the same subject : http://theme.fm/2011/10/how-to-create-tabs-with-the-settings-api-in-wordpress-2590/
Al
October 20th, 2011 12:12 pmThank you for sharing, very useful information for upcoming project.
J-Money
October 20th, 2011 1:29 pmI am sure it was obvious that this question would be coming, but do you have any thoughts as to what would be the best way to add an image upload field using this method?
shawn
October 21st, 2011 12:34 amI’ve asked elsewhere, so might as well ask here also as this is a great tutorial.
I’m working with the bbPress plugin which has a settings page, but no tabs. I want to have my own plugin add tabs to the bbPress settings page, so that I can store all my custom options in a central location instead of creating yet another settings page.
How would I go about ‘extending’ an existing settings page to add tabs and my own options to it?
-because original settings page does not use tabs, there seems to be no ‘home’ to place the original bbPress options under. Just one of the issues I am stuck with.
Would make a unique tutorial, as so far I have yet to find anything that describes adding tabs to existing settings pages…
Dhiren Suthar
October 21st, 2011 2:54 amThanks for the information Friend :)
Very useful post thanks for the sharing
moabi
October 21st, 2011 3:10 ama good option could be:https://github.com/devinsays/options-framework-plugin
Bowe
October 21st, 2011 6:29 amAwesome tutorial! This is great for themes or plugins with a small set of options. I’m using Infinity (http://community.presscrew.com/) to create more advanced custom dashboards, where I don’t even need to write any code to add options or tabs. I love creating themes, but I pretty much suck at php, so Infinity helps me solve this.
Konstantin Kovshenin
October 22nd, 2011 1:31 amSeriously, the Settings API is what you should be using and teaching and as Brad pointed out above: http://theme.fm/2011/10/how-to-create-tabs-with-the-settings-api-in-wordpress-2590/ comes with a demo plugin you can download and play around with too ;)
~ K
chrismccoy
October 24th, 2011 4:01 amnice one, who did the graphic with the tabs?
adumpaul
October 25th, 2011 3:18 amIts realy great tutorial.Thank you.
Marcelo Vidal
October 26th, 2011 5:24 amLooks like the author did the graphic by himself http://dribbble.com/shots/296277-Tabs
Matt
October 26th, 2011 9:00 amThis is fantastic. Thank you!
jockovic
November 1st, 2011 7:54 amThanks for the help on creating tabs, that’s really great now I can do it right. I appreciate the time you took of explaining it and actually showing us the code. There are many others who don’t really share this so thanks.
trouble
January 26th, 2012 12:37 pmHi,
first of all i am not really PHP expert.
I am working on a blog website.
On home page they are looking for recent post to show up.
on archive page it should be all the collection.
I was wondering is there any how i can make categories to get data from recent post (which is on the home page) also same content on the archive.
Here is how i am thinking of getting post from archive and showing it on home page.
Please give me any help will be appreciated.
Thank you.
Sagive
March 2nd, 2012 7:32 amthanks a lot man.. really helpfull :)
Talha Okur
June 5th, 2012 7:12 amSo good! Thank you. I will use it :)
James
September 1st, 2012 12:37 amGreat tutorial – helped me alot.
But now that I’ve created the tabs and it’s working like it should, I came to think WHY…
Why are these tabs a lot more slower than the JQuery UI tabs? I mean.. obviously it’s because we’re loading the page every time we switch between the tabs, but what’s the pro’s for doing it this way.
I’m thinking… it isn’t very user friendly, and could be potentionally annoying to our theme customers, having to wait a second every time they click a new tab?
So my question is: Why make it this way, and not the mere fluid and quicker way (like just show/hide using jQuery, like the JQuery UI example? I simply don’t understand why.
Tony
April 10th, 2013 3:36 amGreat post but the UI for the tabs do not exist in WordPress from the first version. Anyone know what was the first version of WordPress that include the tabs ? In that way, it could be possible to adapt this code for older version of WordPress.
Thanks in advance for those who may have this answer.