Skip to content

Instantly share code, notes, and snippets.

@gyrus
Created August 14, 2012 12:20
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gyrus/3348868 to your computer and use it in GitHub Desktop.
Save gyrus/3348868 to your computer and use it in GitHub Desktop.
WordPress tabs shortcode
/*
* This is the bare minimum CSS necessary to make jQuery UI tabs "work".
* Obviously you'll need to do a lot more styling to make them "good" :)
*/
.ui-tabs-hide { display: none; }
jQuery( document ).ready( function( $ ) {
// Initialize tabs
if ( $( '.pilau-tabs' ).length )
$( '.pilau-tabs' ).tabs();
});
<?php
// This code can be dropped into a theme's functions.php, or - with the right headers - made into a little plugin
/**
* Tabs
*
* The [tab] shortcode should be placed at the top of each section of content meant
* to be placed in a tab. Use the label attributes for the tab label, e.g.
* [tab label="Features"].
*
* The shortcode function itself creates the panes for the tabbed content, and leaves
* a placeholder for the tabs list. The tab labels are gathered into a global array,
* which is then used by a filter on the_content, which constructs the actual tabs
* list, and replaces the placeholder with it.
*
* @uses $pilau_tabs
* @uses wp_enqueue_script()
* @uses shortcode_atts()
* @uses pilau_tabs_id()
* @uses esc_html()
* @return string
*/
add_shortcode( 'tab', 'pilau_tab' );
function pilau_tab( $atts ) {
global $pilau_tabs;
$output = '';
// Enqueue jQuery UI tabs
wp_enqueue_script( 'jquery-ui-tabs' );
// Get attributes
extract( shortcode_atts( array( "label" => __( 'Tab' ) ), $atts ) );
if ( empty( $pilau_tabs ) ) {
// First tab - initialize
$pilau_tabs = array();
$output = '<div class="pilau-tabs">' . "\n" . '#pilau_tabs#' . "\n" . '<section class="content" id="' . pilau_tabs_id( $label ) . '"><div class="post-content">' . "\n";
} else {
// Close a pane, open a pane
$output .= '</div></section>' . "\n" . '<section class="content" id="' . pilau_tabs_id( $label ) . '"><div class="post-content">' . "\n";
}
// No-JS fallback sub-headings
$output .= '<h2 class="hide-if-js">' . esc_html( $label ) . '</h2>' . "\n";
// Add label to array
$pilau_tabs[] = $label;
return $output;
}
/**
* Filter content to place tabs list
*
* @uses $pilau_tabs
* @uses pilau_tabs_id()
* @uses esc_html()
* @param string $content
* @return string
*/
add_filter( 'the_content', 'pilau_tabs_content', 1000 );
function pilau_tabs_content( $content ) {
global $pilau_tabs;
if ( count( $pilau_tabs ) ) {
// Construct the tabs list
$tabs_list = '';
foreach ( $pilau_tabs as $tab ) {
$tabs_list .= '<li><a href="#' . pilau_tabs_id( $tab ) . '">' . esc_html( $tab ) . '</a></li>' . "\n";
}
// Put the list in - hidden if no JS
$content = str_replace( '#pilau_tabs#', '<ul class="tabs hide-if-no-js">' . "\n" . $tabs_list . '</ul>', $content );
// Close the last pane, and the overall tabs wrapper
$content .= '</section>' . "\n" . '</div>';
}
// Reset tabs
$pilau_tabs = array();
return $content;
}
/**
* Helper function to create IDs for tabs
*
* @uses sanitize_title_with_dashes()
* @param string $label
* @param string $prefix
* @return string
*/
function pilau_tabs_id( $label, $prefix = 'tab-' ) {
return sanitize_title_with_dashes( $prefix . $label );
}
@thewebprincess
Copy link

Steve, this is doing almost exactly what I need, but I'm wondering what it would take to extend it to allow for subtabs... I know jquery ui allows for it, could your code be prevailed upon to do the same?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment