Separate multiple Theme Options Pages using Tabs

Themefuse Recently it became a requirement that themes submitted to the WordPress Directory have its options pages residing under the Appearance menu. This is intended to create a more consistent user interface and to standardize the locations where theme components can be found in the admin backend. Now all the theme’s features can be in the same place: If your theme supports custom headers or backgrounds, these can be near your theme options page. It also avoids clashing menu pages, which can happen if a top-level menu entry is chosen.

This shouldn’t be a problem if the theme has only one options page (and this should be the case for most themes) or even 2 pages, but what if the theme options split into 4, 5 or 6 pages? Themes offering advanced functionality like frameworks may require such an interface if it’s offering a lot of options that cover more than one area. In this case, placing many submenu entries under the Appearance menu would be an ugly option, as these would get lost among the other option pages and would create a unnecessarily long and confusing submenu.

The solution in this case is to create one single menu entry for the theme options and use tabs to separate the options pages. Each page will still be stand alone and have its own URI so it can be managed just like any other options page.

In order to create the tabs, we create a function that generates them from an array and outputs the links for them:

function mytheme_admin_tabs( $current = 'general' ) {
	$tabs = array( 'general' => 'General', 'layout' => 'Layout', 'advanced' => 'Advanced' );
	$links = array();
	foreach( $tabs as $tab => $name ) :
		if ( $tab == $current ) :
			$links[] = "<a class='nav-tab nav-tab-active' href='?page=mytheme_options&tab=$tab'>$name</a>";
		else :
			$links[] = "<a class='nav-tab' href='?page=mytheme_options&tab=$tab'>$name</a>";
		endif;
	endforeach;
	echo '<h2>';
	foreach ( $links as $link )
		echo $link;
	echo '</h2>';
}

Now let’s see what we have done:

  • We are storing the tabs (in the form slug => name) in an array called $tabs
  • We are creating the links in an array called $links
  • We are outputting the tabs wrapped in a h2 tag

Note: Replace mytheme_options with your current theme options page’s slug.

The tabs will now show at the top of the options page with the proper links. As you can see, we have added an argument &tab=slug to the page’s URI so we can check which tab is currently viewed. This argument is ignored by the WordPress core and its presence will not affect its functionality in any way.

All we need to know now is the tab we are viewing so we know which page to output. We do this with a simple call to $_GET['tab'] and call the function that generated the options page:

if ( $pagenow == 'themes.php' && $_GET['page'] == 'mytheme_options' ) :
	if ( isset ( $_GET['tab'] ) ) :
		$tab = $_GET['tab'];
	else:
		$tab = 'general';
	endif;
	switch ( $tab ) :
		case 'general' :
			mytheme_general_options();
			break;
		case 'layout' :
			mytheme_layout_options();
			break;
		case 'advanced' :
			mytheme_advanced_options();
			break;
	endswitch;
endif;

Here’s what we did:

  • First we checked if the current page is our theme’s options page, in order not to conflict with any other pages that may use tabs.
  • We checked what tab is set in the URI and defaulted it to ‘general’ because WordPress doesn’t add a tab to the menu link, it does not know about it.
  • We called the required function to generate the options tab, depending on the current tab.

That’s it! Our options page is now separated in tabs. Sorry to disappoint you if you expected it to be more complicated. Forget about jQuery and AJAX content generators that just bloat your code and reduce the user experience. This is a streamline method, simple and clean that lets you control a theme with lots of options.

Hope to see more clean and useful options pages in themes from now on.

If you enjoyed this you may also like

Leave a Reply