Ñako
Ñako

Reputation: 69

Create shortcode to show specific nav menu depending on product category

I need to create a shortcode that displays a specific wordpress menu on a Woocommerce product depending on the category the product belongs to. Both the category and menu are identified by ID but I can't seem to make it work.

Here's my code:

function view_color_menu( $category ) {
    $catarray = get_the_category( $post->ID );
    foreach ($catarray as $cat) {
        $catid = $cat->term_id;
        if ($catid == 31) {
          wp_nav_menu( array( 'menu_id' => '16' ) ); 
        }
        if ($catid == 35) {
          wp_nav_menu( array( 'menu_id' => '17' ) ); 
        }
        if ($catid == 42) {
          wp_nav_menu( array( 'menu_id' => '21' ) ); 
        }
    }
}
add_shortcode('get_color_menu', 'view_color_menu');

Upvotes: 1

Views: 90

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 254363

There are multiple mistakes with your code:

  • get_the_category() only works for WordPress blog post categories, not with product categories (which is a custom taxonomy),
  • wp_nav_menu() function is echoed by default, but inside a shortcode code, it should always be returned.
  • The best way to get the current product post ID is to use:
    • the WordPress functionget_the_ID(),
    • or global $post; with $post->ID.
  • Your settings for wp_nav_menu() seems incorrect as 'menu' parameter accepts, among other things, the menu ID (integer)

Try the following revised code:

add_shortcode('color_menu', 'color_menu_shortcode');
function color_menu_shortcode( $atts ) {
    extract( shortcode_atts( array(
        'product_id'  => get_the_ID()
    ), $atts, 'color_menu' ) );

    // Array of associated term ID with Menu ID pairs
    $data_term_menu = array(
        '31' => '16',
        '35' => '17',
        '42' => '21',
    );

    ob_start(); // start buffering printed content
    
    // Loop through associated Term ID(s) Key / Menu ID(s) value
    foreach ( $data_term_menu as $term_id => $menu_id ) {
        // Check if the current term ID is set in the product
        if ( has_term( intval($term_id), 'product_cat', $product_id ) ) {
            wp_nav_menu( array( 'menu' => intval($menu_id) ) );
        }
    }
    return ob_get_clean(); // Return the buffered content
}

It should work…

Shortcode usage

  • Simple usage in a product page: [color_menu],
  • Or specifying a product ID: [color_menu product_id="18"].

Upvotes: 2

Related Questions