I need display a special menu in each category page in wordpress,

for example I have 3 category: horse,dog,cat

So I must have 3 menu in Menu Settings locations with name: horse,dog,cat

with this code in functions.php I get all categories name:

$category_ids = get_all_category_ids();
foreach($category_ids as $cat_id) {
  $cat_name = get_cat_name($cat_id);
  $arr = $cat_name;

and with this code in functions.php I register menu:

register_nav_menus( array(
  'primary' => 'Main Navigation',
  'secondary' => 'Footer Navigation',

but it's not working and registers only last category, I think we must import register_nav_menus's array in foreach, but I don't know how to do it

2 Answers 2


You're going about this wrongly, I think. The theme_location parameter for wp_nav_menu() is a template location - i.e. a physical location in the template, as defined/registered by the Theme. It's not designed for an arbitrary number of locations based on arbitrary user content.

If you want to output category-specific menus in specific template locations, you would be better off to output your category-specific menu conditionally, with a fallback to a custom nav menu. (Or, better yet: conditionally output a user-assigned custom nav menu, with a fallback to your category menu.)

For example:

<div id="cat-menu">
// if the user has assigned a menu, use it
if ( has_nav_menu( 'cat-menu' ) ) {
    wp_nav_menu( array(
        'theme_location' => 'cat-menu'
    ) );
// otherwise, if this is a category archive index page,
// output a category menu
else if ( is_category() ) {
    // output a list of categories

That said, your issue is mainly a PHP/syntax problem. You need to build an array of menu locations, and then pass that built array to the register function.

// Base menu locations
$menu_locations = array(
    'primary' => 'Main Navigation',
    'secondary' => 'Footer Navigation'

// Get categories
$category_ids = get_all_category_ids();

// Loop through them
foreach( $category_ids as $cat_id ) {
    // Get the Category object
    $cat_obj = get_category( $cat_id );

    // Get the Category Slug
    $cat_slug = $cat_obj->slug;

    // Concatenate it as a menu slug
    $menu_slug = $cat_slug . '-menu';

    // Get the Category Name
    $cat_name = $cat_obj->name;

    // Concatenate it as a menu name
    $menu_name = $cat_name . ' Menu';

    // Now add it to the array of menu locations
    $menu_locations[$menu_slug] = $menu_name;

// Now register
register_nav_menus( $menu_locations );

From using var_dump($arr) it looked like it was still spitting out an array that WordPress didn't know what to do with. Same with $cat_name. You have to tell WordPress, for each id in that array that comes from $category_ids (that you're now calling $cat_id for the individual ids), you want to get each of their names as well as register a menu for each.

$category_ids = get_all_category_ids();
foreach($category_ids as $cat_id):
    $catName = get_cat_name( $cat_id );
    register_nav_menu($cat_id, $catName);

I'm not sure if there is a cleaner solution so that you don't have to register_nav_menu multiple times, but this appears to work. Hope it helps.

Also if you need more explanation on arrays, this course on tutsplus helped me a lot!

  • Also, I'm not sure if you wanted to assign already created menus to this. I wrote it so that you assign them from your dashboard and it'll have the dropdown areas for each category menu.
    – RachieVee
    Jan 14, 2014 at 20:24

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.