Assume you create Programming posts category and add it into your site menu bar. Later you are adding some sub categories like PHP, CSS, HTML, JQuery etc under Programming category. You do not need to add them manually from Menu page(Appearance -> Menus). These sub categories and any future sub category of Programming category will automatically add as sub menu items under the Programming parent menu item on your site’s primary menu.
In this tutorial I shall show you how you will get this for your site.
Adding The Category to Primary Menu
- Navigate to Appearance -> Menus page
- Click on Categories box
- Check mark the category checkbox(es)
- Click on Add to Menu button
- Choose a Display Location if you do not select yet
- Click on Save Menu
As per screenshot you can see that I add the parent category only. You will do the same process and can add multiple parent categories to your menu. If there have any sub category of a parent category, it will automatically add as sub menu items at front end.
Also I set Display Location Primary Menu. You can select another location if you have any.
Adding PHP Snippets
With PHP program we shall add the sub categories to parent category menu item(s). In WordPress there have a filter walker_nav_menu_start_el which filters a menu item’s starting output. It is accepting 4 parameters:
- $item_output: (string) The menu item’s starting HTML output.
- $item: (WP_Post) Menu item data object.
- $depth: (int) Depth of menu item. Used for padding.
- $args: (stdClass) An object of wp_nav_menu() arguments.
Hook this filter like this way add_filter( 'walker_nav_menu_start_el', 'my_callback_function', 10, 4 );
. Inside the callback function, get the all sub categories list of a parent category with wp_list_categories function.
Where will you add the code?
You can add the code into the functions.php file of your theme or any PHP file of your custom plugin.
Full Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
add_filter( 'walker_nav_menu_start_el', 'paulc_add_subcategories_under_parent_category', 10, 4 ); function paulc_add_subcategories_under_parent_category( $item_output, $item, $depth, $args ) { if( $args->theme_location == 'primary' && $item->object === 'category' && $item->type === 'taxonomy' ) { $sub_cats = wp_list_categories( [ 'echo' => 0, 'hide_empty' => 1, 'child_of' => $item->object_id, 'title_li' => '' ] ); if( ! empty( $sub_cats ) ) { $class = "menu-item menu-item-object-{$item->object} menu-item-type-{$item->type}"; $sub_cats = preg_replace( '#<ul\sclass=([^>]*)>#', '<ul class="sub-menu">', $sub_cats ); $sub_cats = preg_replace( '#<li\sclass="([^>]*)">#', '<li class="' . $class . ' $1">', $sub_cats ); $item_output .= '<ul class="sub-menu">' . "\n"; $item_output .= $sub_cats; $item_output .= '</ul>' . "\n"; } } return $item_output; } |
Explaining the code:
- $args->theme_location is checking the display location. I want for primary menu location. So I am checking that there have any active menu at primary location. “primary” is the location slug. It would be unique. You will replace the primary slug with your own theme location slug, if it is different in your theme.
- There have a category menu item in the menu? $item->object variable is checking it.
- wp_list_categories is creating HTML lists of the categories. This is taking one parameters as an array. Here is used following items:
- echo: Saving the category list into a variable for future use. So echo parameter is set as false.
- hide_empty: Do not show those sub categories which have not any post. So it is set to 0.
- child_of: It is taking the parent category ID.
- title_li: By default title is Categories. Do not need title here. Therefore it is set as null.
- If a category have sub category, I am wrapping the category list with
<ul class="sub-menu"></ul>
HTML markup. In WordPress Menu all sub menu items are wrapping with<ul class="sub-menu"></ul>
- Later returning the updated $item_output variable
Periklis Kakarakidis says
I tried it, but it didnt work for me, my theme is woodmart, and woodmart as far as Im concerned uses ‘header’ as the theme_location for header.
Sam says
Great article. Is it possible to add only add first level subcategory under a category? Do you have a solution for that?
vishruti mehta says
can walker_nav_menu_start_el filter works with menu in mobile view?
Paul says
Yes. Not working at your end.
imran says
sorry man its not working in current version off WP 5.4.1 and Woo Version 4.1.0. can u check. that will help lot of people
imran says
hi there
thanks for sharing knowledge. can this be used in woo commerce categories to populate main categories and subcategories. i have huge list of subcategory and not managbel manually
Paul says
Yes. Possible.
Replace this
with
Hope that it will make the tricks