1

I created a Custom Post Type: Product and a Taxonomy assigned to it: Products

So under that Taxonomy I can add different types of products (terms if i'm not mistaken).

When adding new products I get to choose the different terms where it belongs or add new ones.

I want to add this terms to the main navigation menu under 'Products'. As a dropdown in a hierarchical way.

I've tried with custom walker following this example but that displays posts, i need terms in a hierarchical way. Also tried modifying the code but can't make it work, tried add_filter with wp_nav_menu_items to add items to the menu, but it just doesn't work, I don't know the properties of the items objects.

Edit

I had a breakthrough using add_filter and a custom category walker, but it only shows first level.

When I need to display in tree mode:

  • Products
    • A
    • B
      • B-1
    • C
      • C-1
      • C-2
      • C-3

Custon nav walker

class top_bar_walker extends Walker_Nav_Menu {

function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
    $element->has_children = !empty( $children_elements[$element->ID] );
    $element->classes[] = ( $element->current || $element->current_item_ancestor ) ? 'active' : '';
    $element->classes[] = ( $element->has_children && $max_depth !== 1 ) ? 'has-dropdown' : '';

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

function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {
    $item_html = '';
    parent::start_el( $item_html, $object, $depth, $args ); 

    $output .= ( $depth == 0 ) ? '<li class="divider"></li>' : '';

    $classes = empty( $object->classes ) ? array() : (array) $object->classes;

    if( in_array('label', $classes) ) {
        $output .= '<li class="divider"></li>';
        $item_html = preg_replace( '/<a[^>]*>(.*)<\/a>/iU', '<label>$1</label>', $item_html );
    }

if ( in_array('divider', $classes) ) {
    $item_html = preg_replace( '/<a[^>]*>( .* )<\/a>/iU', '', $item_html );
}

    $output .= $item_html;
}

function start_lvl( &$output, $depth = 0, $args = array() ) {
    $output .= "\n<ul class=\"sub-menu dropdown\">\n";
}

}

Filter

add_filter('wp_nav_menu_items','add_menu_products');

function add_menu_products($items) {

            $args = array(
                'show_option_all'    => null,
                'orderby'            => 'name',
                'order'              => 'ASC',
                'style'              => 'list',
                'show_count'         => 0,
                'hide_empty'         => 0,
                'use_desc_for_title' => 0,
                'child_of'           => 0,
                'feed'               => '',
                'feed_type'          => '',
                'feed_image'         => '',
                'exclude'            => '',
                'exclude_tree'       => '',
                'include'            => '',
                'hierarchical'       => 1,
                'title_li'           => null,
                'show_option_none'   => __( 'No categories' ),
                'number'             => null,
                'echo'               => 0,
                'depth'              => 0,
                'current_category'   => 0,
                'pad_counts'         => 0,
                'taxonomy'           => 'products',
                'walker'             => new Categorias_Menu_Walker()
            );

             $cat_menu = wp_list_categories( $args );

$items = '<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children has-dropdown menu-item-120 not-click">
<a href="http://localhost/patmaq/productos/">Productos</a>
<ul class="sub-menu dropdown">'.$cat_menu.'</ul></li>' . $items;
return $items;
}

As you can see I had to hard code the menu item 'Productos' and add the sub-items to it.

And the custom category walker assigned to it

class Categorias_Menu_Walker extends Walker_Category {
function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
    $id_field = $this->db_fields['id'];
    $id = $element->$id_field;
    $this->has_children = !empty( $children_elements[ $id ] );
    //$element->classes[] = ( $element->current || $element->current_item_ancestor ) ? 'active' : '';
    $element->classes[] = ( ($max_depth == 0 || $max_depth > $depth+1 ) && isset( $children_elements[$id]) ) ? 'has-dropdown' : '';

    parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {

    $item_html = '';
    parent::start_el( $item_html, $category, $depth, $args ); 

    $classes = empty( $category->classes ) ? array() : (array) $category->classes;

    if( in_array('label', $classes) ) {
        $output .= '<li class="divider"></li>';
        $item_html = preg_replace( '/<a[^>]*>(.*)<\/a>/iU', '<label>$1</label>', $item_html );
    }

if ( in_array('divider', $classes) ) {
    $item_html = preg_replace( '/<a[^>]*>( .* )<\/a>/iU', '', $item_html );
}

    $output .= $item_html;

}
function start_lvl(&$output, $depth=0, $args=array()) {  
    $output .= "\n<ul class=\"sub-menu dropdown\">\n";  
}  
function end_lvl(&$output, $depth=0, $args=array()) {  
    $output .= "</ul>\n";  
}  
}

In case this helps, i'm using FoundationPress's theme.

Hope someone can help me out, thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.