Add sidebars to navigation menu?

Question

Is it possible to add a sidebar to navigation menu?

I’d like to be able to add sidebars in Appearance > Menus, like I add pages.

I have a way of creating extra sidebars, so that’s not an issue (I could also just register several dedicated sidebars if need be).

Basically I need a way to display widgets in menu, without using any extra plugins.

Is something like that possible? Do I need to extend Walker_Nav_Menu?

EDIT

My menu_walker.php looks like this:

// Allow HTML descriptions in WordPress Menu
remove_filter( 'nav_menu_description', 'strip_tags' );

function my_plugin_wp_setup_nav_menu_item( $menu_item ) {
    if ( isset( $menu_item->post_type ) && 'nav_menu_item' == $menu_item->post_type) {
        $menu_item->description = apply_filters( 'nav_menu_description', $menu_item->post_content );
    }

    return $menu_item;
}

add_filter( 'wp_setup_nav_menu_item', 'my_plugin_wp_setup_nav_menu_item' );

// Menu without icons
class theme_walker_nav_menu extends Walker_Nav_Menu {

    public function display_element($el, &$children, $max_depth, $depth = 0, $args, &$output){
        $id = $this->db_fields['id'];

        if(isset($children[$el->$id])){
            $el->classes[] = 'has_children';
        }

        parent::display_element($el, $children, $max_depth, $depth, $args, $output);
    }

    // add classes to ul sub-menus
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        // depth dependent classes
        $indent = ( $depth > 0  ? str_repeat( "t", $depth ) : '' ); // code indent
        $display_depth = ( $depth + 1); // because it counts the first submenu as 0
        $classes = array(
            'navi',
            ( $display_depth ==1 ? 'first' : '' ),
            ( $display_depth >=2 ? 'navi' : '' ),
            'menu-depth-' . $display_depth
            );
        $class_names = implode( ' ', $classes );

        // build html
        $output .= "n" . $indent . '<ul class="' . esc_attr($class_names) . '">' . "n";
    }

    // add main/sub classes to li's and links
     function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
        global $wp_query;
        $indent = ( $depth > 0 ? str_repeat( "t", $depth ) : '' ); // code indent

        static $is_first;
        $is_first++;
        // depth dependent classes
        $depth_classes = array(
            ( $depth == 0 ? 'main-menu-item' : '' ),
            ( $depth >=2 ? 'navi' : '' ),
            ( $is_first ==1 ? 'menu-first' : '' ),
            'menu-item-depth-' . $depth
        );
        $depth_class_names = esc_attr( implode( ' ', $depth_classes ) );
        // passed classes
        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $class_names = esc_attr( implode( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ) );

        $is_mega_menu = (strpos($class_names,'mega') !== false) ? true : false;
        $use_desc = (strpos($class_names,'use_desc') !== false) ? true : false;
        $no_title = (strpos($class_names,'no_title') !== false) ? true : false;

        if(!$is_mega_menu){
            $class_names .= ' normal_menu_item';
        }

        // build html
        $output .= $indent . '<li id="nav-menu-item-'. esc_attr($item->ID) . '" class="' . esc_attr($depth_class_names) . ' ' . esc_attr($class_names) . '">';
        // link attributes
        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="' . (($item->url[0] == "#" && !is_front_page()) ? home_url() : '') . esc_attr($item->url) .'"' : '';

        $attributes .= ' class="menu-link '.((strpos($item->url,'#') === false) ? '' : 'scroll').' ' . ( $depth > 0 ? 'sub-menu-link' : 'main-menu-link' ) . '"';

        $html_output = ($use_desc) ? '<div class="description_menu_item">'.wp_kses($item->description, allowed_tags()).'</div>' : '';
        $item_output = (!$no_title) ? '<a ' . $attributes . '><span>' . apply_filters( 'the_title', $item->title, $item->ID ) . '</span></a>'.$html_output : $html_output;
        // build html
        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ).(($is_mega_menu)?'<div class="sf-mega"><div class="sf-mega-inner clearfix">':'');
    }

    function end_el( &$output, $item, $depth = 0, $args = array() ) {

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $class_names = esc_attr( implode( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ) );

        $is_mega_menu = (strpos($class_names,'mega') !== false) ? true : false;

        $output .= (($is_mega_menu)?'</div></div>':'') . "</li>n";
    }

}

I also have jquery code that will add the dropdown menu for choosing how many columns I have in megamenu:

jQuery(document).ready(function($) {
    "use strict";

    var $depth_zero = $('#menu-to-edit').find('.menu-item-depth-0');
    var $depth_one = $('#menu-to-edit').find('.menu-item-depth-1');

    var i = 0;
    $depth_zero.find('.field-description').each(function(){
        i++;
        $(this).before('<p class="field-additional description-wide"><label for="add_mega'+i+'">Menu Type<br><select id="add_mega'+i+'" class="additional_input add_mega"><option value="">Default Standard Menu</option><option value="mega1">Mega Menu - Single Column</option><option value="mega2">Mega Menu - 2 Columns</option><option value="mega3">Mega Menu - 3 Columns</option><option value="mega4">Mega Menu - 4 Columns</option><option value="mega5">Mega Menu - 5 Columns</option><option value="mega6">Mega Menu - 6 Columns</option><option value="mega7">Mega Menu - 7 Columns</option></select></p>');
        var classes = $(this).siblings('.field-css-classes').find('input').val();
        var current_c;
        for (var c = 1; c <= 7; c++) {
            current_c = 'mega'+c;
            if(classes.indexOf(current_c) >= 0) {
                $(this).siblings('.field-additional').find('select').val(current_c);
            }
        }
    });

    $depth_one.find('.field-description').each(function(){
        i++;
        var use_desc_state = ($(this).siblings('.field-css-classes').find('input').val().indexOf('use_desc') >= 0) ? ' checked' : '';
        var no_title_state = ($(this).siblings('.field-css-classes').find('input').val().indexOf('no_title') >= 0) ? ' checked' : '';
        $(this).before('<p class="field-additional description-wide"><br><label for="use_desc'+i+'"><input type="checkbox" id="use_desc'+i+'" class="additional_input use_desc" value="use_desc"'+use_desc_state+'>Use description field as HTML content<br></label><label for="no_title'+i+'"><input type="checkbox" id="no_title'+i+'" class="additional_input no_title" value="no_title"'+no_title_state+'>Hide title</label></p>');
    });

    $('.additional_input, .edit-menu-item-classes').change(function() {
        var $parent_item = $(this).closest('.menu-item');
        define_classes($parent_item);
    });

    function define_classes($item){
        var $class_field = $item.find('.field-css-classes input');
        var current_class_value = $class_field.val().replace('use_desc','').replace('no_title','').replace('mega1','').replace('mega2','').replace('mega3','').replace('mega4','').replace('mega5','').replace('mega6','').replace('mega7','').replace('  ',' ');

        var new_class_value = [];

        new_class_value.push(current_class_value.trim());

        if($item.find('.add_mega').length > 0 && $item.find('.add_mega').val() !== ''){
            new_class_value.push($item.find('.add_mega').val());
        }

        if($item.find('.use_desc').length > 0 && $item.find('.use_desc').is(':checked')){
            new_class_value.push('use_desc');
        }

        if($item.find('.no_title').length > 0 && $item.find('.no_title').is(':checked')){
            new_class_value.push('no_title');
        }

        $class_field.val(new_class_value.join(' ').trim());

    }


});

I tried adding this code to extend my memgamenu, but nothing happens.

If I can’t show sidebars here, would it be possible to just add shortcodes in my description field? How would I do this?

When I put the shortcode in the description field, nothing happens. Any help is appereciated.

EDIT

Found a different way. I’ve added a metabox to Menus page that lists all my sidebars, and then I put the content of the sidebars in the descreption field (you need to disable or edit the wp_kses() function on the description field so that it doesn’t strip everything). The function looks like this:

<?php

if ( !class_exists('sidebars_custom_menu')) {
    class sidebars_custom_menu {
        public function add_nav_menu_meta_boxes() {
            add_meta_box(
                'sidebar_menu_add',
                esc_html__('Add Sidebar', 'theme'),
                array( $this, 'nav_menu_link'),
                'nav-menus',
                'side',
                'low'
            );
        }

        public function nav_menu_link() {?>
            <div id="posttype-sidebars" class="posttypediv">
                <div id="tabs-panel-sidebars" class="tabs-panel tabs-panel-active">
                    <ul id ="sidebars-checklist" class="categorychecklist form-no-clear">
                    <?php $i = 0; ?>
                    <?php foreach ( $GLOBALS['wp_registered_sidebars'] as $sidebar ) { ?>
                    <?php
                        $i++;
                        ob_start();
                        dynamic_sidebar($sidebar['id']);
                        $sidebar_html = ob_get_contents();
                        ob_end_clean();
                    ?>
                        <li>
                            <label class="menu-item-title">
                                <input type="checkbox" class="menu-item-checkbox" name="menu-item[-<?php echo $i; ?>][menu-item-object-id]" value="<?php echo $sidebar['id']; ?>"> <?php echo ucwords( $sidebar['name'] ); ?>
                            </label>
                            <input type="hidden" class="menu-item-type" name="menu-item[-<?php echo $i; ?>][menu-item-type]" value="custom">
                            <input type="hidden" class="menu-item-title" name="menu-item[-<?php echo $i; ?>][menu-item-title]" value="<?php echo ucwords( $sidebar['name'] ); ?>">
                            <input type="hidden" class="menu-item-url" name="menu-item[-<?php echo $i; ?>][menu-item-url]" value="">
                            <input type="hidden" class="menu-item-classes" name="menu-item[-<?php echo $i; ?>][menu-item-classes]" value="menu_sidebar use_desc">
                            <input type="hidden" class="menu-item-description" name="menu-item[-<?php echo $i; ?>][menu-item-description]" value="<?php echo htmlentities($sidebar_html); ?>">
                        </li>
                    <?php } ?>
                    </ul>
                </div>
                <p class="button-controls">
                    <span class="list-controls">
                        <a href="/wordpress/wp-admin/nav-menus.php?page-tab=all&amp;selectall=1#posttype-page" class="select-all"><?php esc_html_e('Select All', 'theme'); ?></a>
                    </span>
                    <span class="add-to-menu">
                        <input type="submit" class="button-secondary submit-add-to-menu right" value="<?php esc_html_e('Add to Menu', 'theme');?>" name="add-post-type-menu-item" id="submit-posttype-sidebars">
                        <span class="spinner"></span>
                    </span>
                </p>
            </div>
        <?php }
    }
}

$custom_nav = new sidebars_custom_menu;

add_action('admin_init', array($custom_nav, 'add_nav_menu_meta_boxes'));

Original code from here

0
, , dingo_d 5 years 0 Answers 84 views 0

Leave an answer