How to make tabbed widgets without a plugin

How to make tabbed widgets without a plugin

In this tutorial I’ll show you how to add a tabbed widget just like the one here on WPCrumbs, without using a plugin.

Step 1 · Register the sidebar

First, register the new widget area. If you are using a pre-existent widget area, you can skip this step.

To register the sidebar, add this in functions.php
(NOTE: if you are using a child theme, add the code to the child theme’s functions.php file)

/**
 * Register sidebar
 *
 */
function wcr_widgets_init() {
    register_sidebar(array(
        'name' => esc_html__('Sidebar Tabs', 'wpcrumbs'),
        'id' => 'sidebar-tabs',
        'description' => esc_html__('Add widgets here.', 'wpcrumbs'),
        'before_widget' => '<div id="%1$s" class="tab %2$s">',
        'after_widget' => '</div>',
        'before_title' => '<h3 class="widget-title">',
        'after_title' => '</h3>',
    ));
}

add_action('widgets_init', 'wcr_widgets_init');
Don’t forget to replace wpcrumbs with your theme’s textdomain

Step 2 · Change widgets’ behavior to display as tabs

Add this code in functions.php, to change the widgets’ display method to tabbed:

/**
 * Empty widget title
 * 
 * @param string $widget_title
 * @return
 */
function empty_widget_title($widget_title) {
	return;
}

/**
 * Get first X widgets from a defined widget area (sidebar) and reorganize their content using tabs
 * 
 * @global array $wp_registered_widgets
 * @param string $sidebar_id
 */
function tabbed_dynamic_sidebar($sidebar_id, $widgets_no = 3) {
    global $wp_registered_widgets;

    $sidebars_widgets = wp_get_sidebars_widgets();
    if (empty($sidebars_widgets[$sidebar_id])) {
        return;
    }

    $tabs = array();
    $tabs_content = array();

    add_filter('widget_title', 'empty_widget_title'); // add filter to remove widget titles

    foreach ($sidebars_widgets[$sidebar_id] as $key => $id) {
        if ($widgets_no < $key + 1) {
            break;
        }

        if (empty($wp_registered_widgets[$id]['callback'][0]->id_base)) {
            continue;
        }

        $instance = get_option('widget_' . $wp_registered_widgets[$id]['callback'][0]->id_base);
        $instance = $instance[$wp_registered_widgets[$id]['params'][0]['number']];
        $class_name = get_class($wp_registered_widgets[$id]['callback'][0]);

        $tabs[$key] = sprintf('<li class="%s" data-key="%d"><h2>%s</h2></li>', ($key === 0 ? 'active' : ''), $key, $instance['title']);
        $tabs_content[$key] = get_the_widget($class_name, $instance, array('before_widget' => '', 'after_widget' => '', 'widget_id' => $wp_registered_widgets[$id]['id']));
    }

    remove_filter('widget_title', 'empty_widget_title'); // remove previous filter

    $tabs_nav = sprintf('<ul class="tabs-nav">%s</ul> ', implode(' ', $tabs));

    echo sprintf('<section id="%s" class="widget">%s <div class="tabs-content">%s</div></section>', $sidebar_id, $tabs_nav, implode(' ', $tabs_content));
}

Step 3 · Add the JavaScript

Next, add this snippet in your theme’s javascript file where all other script are initialized. There is no universal name for the theme’s javascript file, so you’ll have to find the exact file. It might be something like custom.js or theme.js.

/* ------------------------------------------------------------------
SIDEBAR TABS
------------------------------------------------------------------ */
$('#sidebar-tabs').on('click', '.tabs-nav li', function() {
    var tab = $(this).data('key');

    // set active tab from navigation
    $('.tabs-nav li').removeClass('active');
    $(this).addClass('active');

    // set active tab from content
    $('.tabs-content ol').hide();
    $('.tabs-content ol').eq(tab).show();
});

Step 4 · Style the tabbed widget

Add your css styles in style.css
(NOTE: if you are using a child theme, add the code to the child theme’s style.css file, so you won’t lose your modifications when parent theme is updated)

/*--------------------------------------------------------------
## Tabbed Widget
--------------------------------------------------------------*/
#sidebar-tabs {
    position: relative;
    padding-top: 90px;
    border-top: 0;
}

#sidebar-tabs .tabs-nav {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    padding: 0;
    margin: 0;
}

#sidebar-tabs .tabs-nav li {
    cursor: pointer;
    width: 50%;
    display: inline-block;
    float: left;
    text-transform: uppercase;
    font-size: 1.1rem;
    font-weight: 700;
    color: #353535;
    letter-spacing: 2px;
    margin: 0 0 20px;
    background: rgba(200, 200, 200, .15);
    padding: 12px 10px 12px 30px;
    border-top: 10px solid rgba(200, 200, 200, .15);
}

#sidebar-tabs .tabs-nav li.active {
    font-weight: bold;
    background: #fff;
}

#sidebar-tabs .tabs-nav li:first-child {
    border-radius: 3px 0 0 0;
}

#sidebar-tabs .tabs-nav li:last-child {
    border-radius: 0 3px 0 0;
}

#sidebar-tabs .tabs-nav li h2 {
    font-size: 1.1rem;
    font-weight: 700;
    color: #353535;
    letter-spacing: 2px;
    margin: 0;
}

#sidebar-tabs .tabs-content ol {
    display: none;
    counter-reset: li;
    margin-left: 0;
    padding-left: 0;
}

#sidebar-tabs .tabs-content ol:first-of-type {
    display: block;
}

.tabs-content ol > li {
    position: relative;
    margin: 0 0 30px 42px;
    list-style: none;
}

.tabs-content ol > li:before {
    content: counter(li);
    counter-increment: li 1;
    position: absolute;
    top: -1px;
    left: -72px;
    width: 60px;
    font-weight: 700;
    padding: 4px 4px 4px 30px;
    background: rgba(200, 200, 200, .15);
    box-sizing: border-box;
}

.tabs-content h3 {
    font-size: 1.1rem;
    font-weight: normal;
    margin: 0;
}

This will of course style the widget like the one on WPCrumbs, so feel free to create your own styles to integrate the tabbed widget with you theme.

Step 5 · Display the sidebar

To display the sidebar, use the tabbed_dynamic_sidebar function instead of dynamic_sidebar everywhere you need to display sidebar-tabs widget area.

<?php tabbed_dynamic_sidebar('sidebar-tabs', 2); ?>
Leave a Reply

Get your fix of
all cool things WordPress

DigitalOcean hosting coupon 10$ coupon

for DigitalOcean hosting.
Sammy-approved.

Get this deal