Creating WordPress Shortcodes for jQuery Tools Tabs

Example Tabs Shortcode Output

The following code is my solution for creating a set of WordPress shortcodes to generate the HTML needed to reproduce the minimal setup for tabs using the jQuery Tools library.

The Problem

I wanted my client to be able to create a set of jQuery Tools tabs using the following shortcodes:

[tabgroup]
[tab title="Tab 1"]Tab 1 content goes here.[/tab]
[tab title="Tab 2"]Tab 2 content goes here.[/tab]
[tab title="Tab 3"]Tab 3 content goes here.[/tab]
[/tabgroup]

In the above scenario, I need my [tab] shortcode to process each tab sending the tab title and content back to my [tabgroup] shortcode function. Then, my [tabgroup] function needs to output the following HTML:

<!-- the tabs -->
<ul class="tabs">
<li><a href="#">Tab 1</a></li>
<li><a href="#">Tab 2</a></li>
<li><a href="#">Tab 3</a></li>
</ul>
<!-- tab "panes" -->
<div class="panes">
<div>First tab content. Tab contents are called "panes"</div>
<div>Second tab content</div>
<div>Third tab content</div>
</div>

The Solution

In order to produce the above HTML, I choose to store the output of my [tab] shortcode function in a global variable. Then, once the recursion is finished in the [tab] function, I process that global variable in the [tabgroup] function and return the output.

Here’s the code to make that happen:

/*
* jQuery Tools - Tabs shortcode
*/
add_shortcode( 'tabgroup', 'jqtools_tab_group' );
function jqtools_tab_group( $atts, $content ){
$GLOBALS['tab_count'] = 0;

do_shortcode( $content );

if( is_array( $GLOBALS['tabs'] ) ){
foreach( $GLOBALS['tabs'] as $tab ){
$tabs[] = '<li><a class="" href="#">'.$tab['title'].'</a></li>';
$panes[] = '<div class="pane"><h3>'.$tab['title'].'</h3>'.$tab['content'].'</div>';
}
$return = "\n".'<!-- the tabs --><ul class="tabs">'.implode( "\n", $tabs ).'</ul>'."\n".'<!-- tab "panes" --><div class="panes">'.implode( "\n", $panes ).'</div>'."\n";
}
return $return;
}

add_shortcode( 'tab', 'jqtools_tab' );
function jqtools_tab( $atts, $content ){
extract(shortcode_atts(array(
'title' => 'Tab %d'
), $atts));

$x = $GLOBALS['tab_count'];
$GLOBALS['tabs'][$x] = array( 'title' => sprintf( $title, $GLOBALS['tab_count'] ), 'content' =>  $content );

$GLOBALS['tab_count']++;
}

I hope this solution helps some of you guys out there. In addition, if you see any way to refine my code, please let me know in the comments.

NOTE: For information on setting up the JavaScript and CSS to power and style the above tabs, please see the jQuery Tools Minimal Setup for Tabs.