Reputation: 133
i have a long list of categories and sub categories and even a sub categories of sub categories and it take so much time to pick one by one in menu section of wordpress and then re-arrange the hierarchy of categories and their sub categories
I search about it and i did not find anything helping about this so I was wondering if any of your guys can help me with any function or suggest me any plugin which can add these categories in menu automatically
Thanks
Upvotes: 6
Views: 13285
Reputation: 789
If someone is still looking for a solution without a plugin, I got this working version using the wp_nav_menu
walker
.
Basically, I place only first level category in my Appearence > Menu and I loop through posts of those categories in my start_el function.
Here my walker function:
class AWP_Menu_Walker extends Walker_Nav_Menu {
function start_el(&$output, $item, $depth=0, $args=[], $id=0) {
$open = '';
$current = '';
$sub_menu = '';
$menuItemFont = 'font-sans text-sm font-light ';
$subMenuItemFont = 'text-sm font-sans font-light ';
$current_element_array = array( 'current-menu-item' );
$current_element_markers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' );
$current_class = array_intersect( $current_element_markers, $item->classes );
$current_element = array_intersect( $current_element_array, $item->classes );
if ($item->object == 'category') {
$category_slug = get_category($item->object_id);
$args = array(
'tag' => get_queried_object()->slug,
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'menu_order',
'order' => 'ASC',
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $category_slug->slug, // here I get the slug of indexed category
),
)
);
$posts = get_posts( $args );
$current_url = get_permalink();
foreach ($posts as $post) :
$post_url = get_permalink($post->ID);
if ($post_url == $current_url) {
$current = 'text-red-500 ';
}
$sub_menu .= '<li class="select-none my-2 truncate- leading-tight ' . $current . $subMenuItemFont . ' px-4 pl-6"><a title="' . esc_html($post->post_title) . '" href="' . $post_url . '">' . esc_html($post->post_title) . '</a></li>';
endforeach;
}
// conditional styles for menu items
if (!empty($current_element)) {
$menuItemFont .= 'text-red-500 ';
$subMenuItemFont .= 'text-red-500 ';
} else {
$menuItemFont .= 'text-zinc-800 ';
$subMenuItemFont .= 'text-zinc-600 ';
}
// This set the <details> open if current item is whitin
if (!empty($current_class)) {
$open = 'open';
}
if (!$args->walker->has_children) {
if ($item->menu_item_parent == 0){
if ($item->object == 'category') {
$output .= '<details ' . $open . ' class="' . $menuItemFont . ' pl-4">';
$output .= '<summary class="select-none cursor-pointer truncate- ' . $menuItemFont . $color . $current . '"><span class="pl-4">' . esc_html($item->title) . '</span></summary>';
$output .= $sub_menu;
} else {
$output .= '<li class="select-none truncate- ' . $current . $menuItemFont . $color . ' pl-8 pr-2"><a title="' . esc_html($item->title) . '" href="' . esc_url($item->url) . '">' . esc_html($item->title) . '</a></li>';
}
}
} else {
$output .= '<details ' . $open . ' class="' . $menuItemFont . ' pl-4">';
$output .= '<summary class="select-none cursor-pointer truncate- ' . $menuItemFont . $color . $current . '"><span class="pl-4">' . esc_html($item->title) . '</span></summary>';
}
}
function end_el(&$output, $item, $depth = 0, $args = Array()){ // closing li a span
if ($item->menu_item_parent == 0){
$output .= '</details>';
}
if ($args->walker->has_children) {
$output .= '</details>';
}
}
}
/* Walker nav menu */
Then I call this in my template:
wp_nav_menu(
array(
'theme_location' => 'menu-1',
'menu_id' => 'primary-menu',
'items_wrap' => '<ul id="%1$s" class="%2$s font-display flex flex-col gap-1" aria-label="submenu">%3$s</ul>',
'walker' => new AWP_Menu_Walker(),
)
);
I set my categories in the menu:
This is the result:
Upvotes: 0
Reputation: 41
I confirm a solution with a JC Submenu plugin. Works perfect. I used the Astra theme and add a filter in theme functions.php to work on it.
//Enable compatibility with theme custom menu walkers
add_filter('jcs/enable_public_walker', 'jc_disable_public_walker');
function jc_disable_public_walker($default){
return false;
}
Upvotes: 4
Reputation: 315
There's a plugin: https://wordpress.org/plugins/jc-submenu/
Its old but still works in some themes.
Upvotes: 4