Quantcast
Channel: WordPress › Support » Forum: Hacks - Recent Topics
Viewing all articles
Browse latest Browse all 8245

themarcthomas on "Multiple groups of grandchildren break WordPress Walker class"

$
0
0

'm currently integrating Foundation 5's accordion and WordPress via a walker class. The original was made by AWshout here: https://gist.github.com/awshout/5375157

The side menu on the left is an accordion thing which is working fine until you add a third level of child page. I currently have a Walker class (not sure if you’re familiar with them but they allow WordPress menus to be styled better.)

class Section_Nav_Walker extends Walker_Nav_Menu {

    /**
     * @see Walker_Nav_Menu::start_lvl()
     *
     * @param string $output Passed by reference. Used to append additional content.
     * @param int $depth Depth of page. Used for padding.
    */
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        $output .= '<div class="content" data-section-content><ul class="side-nav">';
    }   

    /**
     * @see Walker::end_lvl()
     *
     * @param string $output Passed by reference. Used to append additional content.
     * @param int $depth Depth of page. Used for padding.
     */
    function end_lvl( &$output, $depth = 0, $args = array() ) {
        // close .side-nav .content and .section
        $output .= '</ul></div></div>';
    }

    /**
     * @see Walker_Nav_Menu::start_el()
     *
     * @param string $output Passed by reference. Used to append additional content.
     * @param object $item Menu item data object.
     * @param int $depth Depth of menu item. Used for padding.
     * @param object $args
     */
    function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {

        $class_names = $value = '';

    $classes = empty( $item->classes ) ? array() : (array) $item->classes;
    $classes[] = 'menu-item-' . $item->ID;
    $classes[] = ( $depth == 0 ) ? 'title' : '';
    $classes[] = ( $args->has_children ) ? 'has-dropdown' : '';
    $classes[] = ( in_array('current-menu-item', $classes) && !in_array('active', $classes) ) ? 'active' : '';

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
        $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';

        $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
        $id = $id ? ' id="' . esc_attr( $id ) . '"' : '';

    // create sections
    $section_class = ( $depth == 0 && in_array('active', $classes) ) ? 'section active' : 'section';
    $section_class = ( $depth <= 1 && in_array('active', $classes) ) ? 'section active' : 'section';
    // $section_class = 'section';
    $output .= ( $depth == 0 ) ? '<div class="' . $section_class . '">' : '';

    // if top level use p.title else use li in dropdown
        $output .= ( $depth == 0 ) ? '<p data-section-title' . $id . $value . $class_names .'>' : '<li' . $id . $value . $class_names .'>';

        $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 ) . '"' : '';

    // if top level and has dropdown do not use url
    if ( $depth == 0 && $args->has_children ) {
        $attributes .= ' href="#"';
    }
    // else use url
    elseif ( !empty( $item->url ) ) {
        $attributes .= ' href="' . esc_attr( $item->url ) . '"';
    }

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

    // close .section if there is no dropdown
    $item_output .= ( $depth == 0 && !$args->has_children ) ? '</div>' : '';

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
      }

    /**
     * @see Walker::end_el()
     *
     * @param string $output Passed by reference. Used to append additional content.
     * @param object $item Page data object. Not used.
     * @param int $depth Depth of page. Not Used.
     */
    function end_el( &$output, $item, $depth = 0, $args = array() ) {
        if ( $depth > 0 ) {
            $output .= "</li>";
        }
    }

    /**
     * Traverse elements to create list from elements.
     *
     * Display one element if the element doesn't have any children otherwise,
     * display the element and its children. Will only traverse up to the max
     * depth and no ignore elements under that depth.
     *
     * This method shouldn't be called directly, use the walk() method instead.
     *
     * @see Walker::start_el()
     * @since 2.5.0
     *
     * @param object $element Data object
     * @param array $children_elements List of elements to continue traversing.
     * @param int $max_depth Max depth to traverse.
     * @param int $depth Depth of current element.
     * @param array $args
     * @param string $output Passed by reference. Used to append additional content.
     * @return null Null on failure with no changes to parameters.
     */

    function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
        if ( !$element ) {
            return;
        }

        $id_field = $this->db_fields['id'];

        //display this element
        if ( is_object( $args[0] ) ) {
           $args[0]->has_children = ! empty( $children_elements[$element->$id_field] );
        }

        parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output);
    }
}

The problem is that there’s something in that file that can’t work out how to cope with more than one set of grandchildren in a list and that’s when the menu breaks. What I need ideally is something that can cope with a menu like this:

  • Parent
    • Child
      • Grandchild
    • Child
      • Grandchild

Any ideas what I might need to change in that file? Have tried a bunch of stuff but every time I just end up reformatting bits – I think that I need to add something that navigates back up a level before closing the list.

I’d really appreciate a hand, Marc


Viewing all articles
Browse latest Browse all 8245

Trending Articles