Custom shortcode for creating tabs

I am currently trying to create a shortcode for WordPress that creates tabs, I know there are available shortcodes.. But I am trying to learn how to write them myself.

Currently I am generating the tab menu items, but i am stuck with placing the content in an entirely new div.

Read More

Front end Usage:

[tabs]
 [tab title="tab" active="y" id="home"]home[/tab]
 [tab title="tab2" active="n" id="about"]about[/tab]
 [tab title="tab3" active="n" id="help"]help[/tab]
[/tabs]

And then the code:

function tabs_group( $atts, $content = null ) {  
    extract(shortcode_atts(array(  
    'id' => '',
    'class' => ''
    ), $atts));  

    $output  = '<ul class="nav nav-tabs '.$class.'"  ';

    if(!empty($id))
        $output .= 'id="'.$id.'"';

    $output .='>'.do_shortcode($content).'</ul>';

    return $output;  
}  

add_shortcode("tabs", "tabs_group");

function tab($atts, $content = null) {  
    extract(shortcode_atts(array(  
    'id' => '',
    'title' => '',
    'active'=>'n' 
    ), $atts));  
    if(empty($id))
        $id = 'tab_item_'.rand(100,999);

    $output = '<li class="'.($active == 'y' ? 'active' :'').'">
                <a href="#'.$id.'">'.$title.'</a>
                </li>';  
    $output .= '<div class="tab-content">
                 <div class="tab-pane active" id="'.$id.'">'.$content.'</div>
                 <div class="tab-pane"  id="'.$id.'">'.$content.'</div>
                 <div class="tab-pane" id="'.$id.'">'.$content.'</div>
                </div>';
    return $output;
}
add_shortcode("tab", "tab");

it currently returns:

<ul class="nav nav-tabs">
 <li class="active">
                <a href="#home">tab</a>
                </li><div class="tab-content">
                 <div class="tab-pane active" id="home">home</div>
                 <div class="tab-pane"  id="home">home</div>
                 <div class="tab-pane" id="home">home</div>
                </div>
 <li class="">
                <a href="#about">tab2</a>
                </li><div class="tab-content">
                 <div class="tab-pane active" id="about">about</div>
                 <div class="tab-pane"  id="about">about</div>
                 <div class="tab-pane" id="about">about</div>
                </div>
 <li class="">
                <a href="#help">tab3</a>
                </li><div class="tab-content">
                 <div class="tab-pane active" id="help">help</div>
                 <div class="tab-pane"  id="help">help</div>
                 <div class="tab-pane" id="help">help</div>
                </div>
</ul>

and i need it to return:

<ul class="nav nav-tabs "  >
 <li class="active">
    <a href="#home">tab</a>
 </li>
 <li class="">
    <a href="#about">tab2</a>
 </li>
 <li class="">
    <a href="#help">tab3</a>
 </li>
</ul>

<div class="tab-content">
 <div class="tab-pane active" id="home">blah</div>
 <div class="tab-pane" id="about">blah</div>
 <div class="tab-pane" id="help">blah</div>
</div>

I have added to the output, thank you Obmerk Kronen.

Any Help Greatly Appreciated.

Related posts

Leave a Reply

3 comments

  1. The problem here is that you need to add your divs after do_shortcode($content) : while parsing tab shorcodes, you need to keep your divs somewhere to be able to output them after.

    A simple way (not nicest way) for doing this could be using a global var, e.g. :

    add_shortcode('tabs', 'tabs_group');
    add_shortcode('tab', 'tab');
    
    // this variable will hold your divs
    $tabs_divs = '';
    
    function tabs_group( $atts, $content = null ) {
        global $tabs_divs;
    
        // reset divs
        $tabs_divs = '';
    
        extract(shortcode_atts(array(  
            'id' => '',
            'class' => ''
        ), $atts));  
    
        $output = '<ul class="nav nav-tabs '.$class.'"  ';
    
        if(!empty($id))
            $output .= 'id="'.$id.'"';
    
        $output.='>'.do_shortcode($content).'</ul>';
        $output.= '<div class="tab-content">'.$tabs_divs.'</div>';
    
        return $output;  
    }  
    
    
    function tab($atts, $content = null) {  
        global $tabs_divs;
    
        extract(shortcode_atts(array(  
            'id' => '',
            'title' => '',
            'active'=>'n' 
        ), $atts));  
    
        if(empty($id))
            $id = 'tab_item_'.rand(100,999);
    
        $activeClass = $active == 'y' ? 'active' :'';
        $output = '
            <li class="'.$activeClass.'">
                <a href="#'.$id.'">'.$title.'</a>
            </li>
        ';
    
        $tabs_divs.= '<div class="tab-pane '.$activeClass.'" id="'.$id.'">'.$content.'</div>';
    
        return $output;
    }
    
  2. you do not currently have the content part of the divs in your content

    $output .= '<div class="tab-content">
     <div class="tab-pane active" id="'.$id.'">'.$title.'</div>
     <div class="tab-pane"  id="'.$id.'">'.$title.'</div>
     <div class="tab-pane" id="'.$id.'">'.$title.'</div>
    </div>'
    
  3. <?php
    //  my shortcode look like this.
    [tabgroup] 
        [tab title="Your title #1" class="active" ]
         Your Description here #1
        [/tab]  
        [tab title="Your title #2" ]  
         Your Description here  #2 
        [/tab]    
        [tab title="Your title #3" ]   
         Your Description here #3
        [/tab]    
    [/tabgroup]
    
    add_shortcode( 'tab', 'ease_tabs' );
    function ease_tabs( $atts, $content ){
        extract(shortcode_atts(array(
            'title' => 'Tab',
            'class' => false,
        ), $atts));
    
         $x = isset($GLOBALS['tab_count'])?$GLOBALS['tab_count']:0; 
         $GLOBALS['tab_count'] = isset($GLOBALS['tab_count'])?$GLOBALS['tab_count']:0;          
    
         $GLOBALS['tabs'][$GLOBALS['tabs_count']][$x] = array( 
                'title'     => $title   ,
                'class'     => $class   ,
                'content'   => $content ,
         );
    
         $GLOBALS['tab_count']++;
    
     }
    
    add_shortcode( 'tabgroup', 'ease_tabgroup' );
    function ease_tabgroup( $atts, $content ){
    
        if( isset( $GLOBALS['tabs_count'] ) )
          $GLOBALS['tabs_count']++;
        else
          $GLOBALS['tabs_count'] = 0;
    
        do_shortcode( $content ); 
    
        if( is_array( $GLOBALS['tabs'][$GLOBALS['tabs_count']] ) ){
    
            $tabs=array();
            $panes=array();
    
            foreach( $GLOBALS['tabs'][$GLOBALS['tabs_count']] as $tab ){
    
            $panes_class  = ( !empty($tab["class"]) &&  $tab['class'] == "active" ) ? 'tab-pane active' : 'tab-pane';
            $__title = preg_replace('/[^a-zA-Z0-9._-]/', '', strtolower($tab['title'])  );     
            $tabs[] = '<li  role="presentation" class="'.$tab['class'].'" >
                            <a href="#'.$__title.'" data-toggle="tab">'.$tab['title'].'</a>
                      </li>';
            $panes[] = sprintf( '<div class="%s" id="%s"> %s </div>',$panes_class, $__title, $tab['content']  );
    
            }
    
    
            $return = "n".'<div role="tabpanel">
                                <ul role="tablist" class="nav nav-tabs">'
                                    .implode( "n", $tabs ).
                                '</ul>'."n".
                                '<div class="tab-content">'
                                        .implode( "n", $panes ).
                                '</div>
                            </div>'."n";       
        }   
        return do_shortcode( sprintf('<div class="tp-tabs"> %s </div>',  $return));
    }