WordPress Custom Menu Widget ==> change to 2-column

I am trying to create a Custom Menu Widget that has two columns (i.e., wherein I can select two different menus and have them display side-by-side within a single sidebar widget).

I found a tutorial on how to create a two column text widget, however I cannot figure out how to edit the Custom Menu widget functions to add and implement an additional menu — my attempts to create an additional menu variable (i.e., “$menus1” and “$menus2” below) break WordPress (“unexpected T string” error).

Read More

Does the “$instance” array have a pre-defined key called ‘nav_menu’ or are this key and its value created by the “form” function? If the latter, can I define ‘nav_menu1’ and ‘nav_menu2’ keys (I tried this before but also got the “unexpected T string” error)?

<?php
/**
 * Custom Menu widget copied from default WP Widget Class and adjusted for 2-columns
 */

class SO_ABC_Tag_List_Widget_2col extends WP_Widget {

    function __construct() {
        $widget_ops = array( 'description' => __('By adding this widget you can select your alphabetical tags menu to display on your website.') );
        parent::__construct( 'so_abc_tags_2col', __('SO ABC Tag List 2 col'), $widget_ops );
    }

    function widget($args, $instance) {
        // Get menu
        $nav_menu1 = ! empty( $instance['nav_menu'] ) ? wp_get_nav_menu_object( $instance['nav_menu'] ) : false;
        $nav_menu2 = ! empty( $instance['nav_menu'] ) ? wp_get_nav_menu_object( $instance['nav_menu'] ) : false;

        if ( !$nav_menu )
            return;

        $instance['title'] = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );

        echo $args['before_widget'];

        if ( !empty($instance['title']) )
            echo $args['before_title'] . '<i class="icon-tags"></i> ' . $instance['title'] . $args['after_title'];

<div style="float: left; width: 45%">
        wp_nav_menu( array( 'fallback_cb' => '', 'menu' => $nav_menu1 ) );
</div> 

<div style="float: left; width: 45%"></div>     
        wp_nav_menu( array( 'fallback_cb' => '', 'menu' => $nav_menu2 ) );
</div>
        echo $args['after_widget'];
    }

    function update( $new_instance, $old_instance ) {
        $instance['title'] = strip_tags( stripslashes($new_instance['title']) );
        $instance['nav_menu'] = (int) $new_instance['nav_menu'];
        $instance['nav_menu'] = (int) $new_instance['nav_menu'];
        return $instance;
    }

    function form( $instance ) {
        $title = isset( $instance['title'] ) ? $instance['title'] : '';
        $nav_menu1 = isset( $instance['nav_menu'] ) ? $instance['nav_menu'] : '';
        $nav_menu2 = isset( $instance['nav_menu'] ) ? $instance['nav_menu'] : '';

        // Get menus
        $menus1 = get_terms( 'nav_menu', array( 'hide_empty' => false ) );
        $menus1 = get_terms( 'nav_menu', array( 'hide_empty' => false ) );

        // If no menus exists, direct the user to go and create some.
        if (( !$menus1  ) AND ( !menus2 )) {
            echo '<p>'. sprintf( __('No menus have been created yet. <a href="%s">Create some</a>.'), admin_url('nav-menus.php') ) .'</p>';
            return;
        }
        ?>
        <p>
            <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:') ?></label>
            <input type="text" class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" value="<?php echo $title; ?>" />
        </p>
        <p>
            <label for="<?php echo $this->get_field_id('nav_menu'); ?>"><?php _e('Select Menu:'); ?></label>
            <select id="<?php echo $this->get_field_id('nav_menu'); ?>" name="<?php echo $this->get_field_name('nav_menu'); ?>">
        <?php
            foreach ( $menus1 as $menu1 ) {
                echo '<option value="' . $menu1->term_id . '"'
                    . selected( $nav_menu, $menu1->term_id, false )
                    . '>'. $menu1->name . '</option>';
            }
        ?>
            </select>
        </p>
        <p>
            <label for="<?php echo $this->get_field_id('nav_menu'); ?>"><?php _e('Select Menu:'); ?></label>
            <select id="<?php echo $this->get_field_id('nav_menu'); ?>" name="<?php echo $this->get_field_name('nav_menu'); ?>">
        <?php
            foreach ( $menus2 as $menu2 ) {
                echo '<option value="' . $menu2->term_id . '"'
                    . selected( $nav_menu, $menu2->term_id, false )
                    . '>'. $menu2->name . '</option>';
            }
        ?>
            </select>
        </p>
        <?php
    }
}

Related posts

Leave a Reply

1 comment

  1. You have html and php code mixed together which certainly would cause an error

    if ( !empty($instance['title']) )
            echo $args['before_title'] . '<i class="icon-tags"></i> ' . $instance['title'] . $args['after_title'];
    

    wp_nav_menu( array( ‘fallback_cb’ => ”, ‘menu’ => $nav_menu1 ) );

        wp_nav_menu( array( 'fallback_cb' => '', 'menu' => $nav_menu2 ) );
    

    echo $args[‘after_widget’];
    }

    Fix that first then see if it still doesnt work.
    You also haven’t finished changing all the references from menu1 to menu2. And yes you will need to change the the key for $instance and probably get_terms – plus theres some field id stuff in the form function thats duplicated.

    But I’m not sure what you want to achieve.
    What you’re trying to do will output 2 different menus in a single widget.
    My suggestion would be to put two menu widgets in the same area and then use css to make them go side by side.