askdesign
12/13/2015 - 3:30 PM

How to conditionally replace menu in Primary Navigation with Product Categories and their terms on WooCommerce pages in Genesis

Sridhar Katakam

// Here’s a different approach using action hooks instead of a filter hook in functions.php for the same (just recording this here for my future reference):

// Add Product Categories Navigation Menu
add_theme_support( 'genesis-menus', array(
	'primary'   => __( 'Primary Navigation Menu', 'genesis' ),
	'secondary' => __( 'Secondary Navigation Menu', 'genesis' ),
	'product_categories' => __( 'Product Categories Navigation Menu', 'genesis' ),
) );

// Show Product Categories Navigation Menu instead of Primary Navigation Menu on WooCommerce pages
add_action( 'genesis_header', 'sk_wc_nav' );
function sk_wc_nav() {

	// if we are not on a page which uses WooCommerce templates (cart and checkout are standard pages with shortcodes and thus are not included), abort
	if ( ! ( is_woocommerce() ) ) {
		return;
	}

	// Remove the primary navigation menu
	remove_action( 'genesis_after_header', 'genesis_do_nav' );

	// Display a menu assigned to Product Categories Navigation Menu Theme Location
	add_action( 'genesis_after_header', 'sk_do_product_categories_nav' );

}

// Function to display a menu assigned to Product Categories Navigation Menu Theme Location
function sk_do_product_categories_nav() {

	printf( '<nav %s><div class="wrap">', genesis_attr( 'nav-primary' ) );
		wp_nav_menu( array(
			'theme_location' => 'product_categories',
			'container'      => false,
			'fallback_cb'    => false,
			'menu_class'     => 'genesis-nav-menu',
		) );
	echo '</div></nav>';

}

// Add "menu-item" class to all list item elements in the menu output by JC Submenu
add_action( 'jcs/item_classes', 'jc_edit_item_classes' );
function jc_edit_item_classes( $classes ) {

	$classes[] = "menu-item";
	return $classes;
}

// Make Font Awesome available
add_action( 'wp_enqueue_scripts', 'enqueue_font_awesome' );
function enqueue_font_awesome() {

	if ( ! ( is_woocommerce() ) ) {
		return;
	}

	wp_enqueue_style( 'font-awesome', '//maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css' );

	wp_enqueue_script( 'wc-js', get_stylesheet_directory_uri() . '/js/wc-js.js', array( 'jquery' ), '', true );

}

// ‘Product Categories’ would need to be assigned to “Product Categories Navigation Menu” location in this approach.
// Add the following in child theme’s functions.php:

// Assign a menu conditionally in Primary Navigation Menu location
add_filter( 'wp_nav_menu_args', 'replace_menu_in_primary' );
function replace_menu_in_primary( $args ) {

	// Affect only Primary Navigation Menu
	if ( $args['theme_location'] != 'primary' ) {
		return $args;
	}

	// Assign a menu named "Product Categories" if we are on a page which uses WooCommerce templates (cart and checkout are standard pages with shortcodes and thus are not included)
	if ( is_woocommerce() ) {
		$args['menu'] = 'Product Categories';
	}

	return $args;
}

// Add "menu-item" class to all list item elements in the menu output by JC Submenu
add_action( 'jcs/item_classes', 'jc_edit_item_classes' );
function jc_edit_item_classes( $classes ) {

	$classes[] = "menu-item";
	return $classes;
}

// Load Font Awesome and custom JS on all WooCommerce pages
add_action( 'wp_enqueue_scripts', 'enqueue_font_awesome' );
function enqueue_font_awesome() {

	if ( ! ( is_woocommerce() ) ) {
		return;
	}

	wp_enqueue_style( 'font-awesome', '//maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css' );

	wp_enqueue_script( 'wc-js', get_stylesheet_directory_uri() . '/js/wc-js.js', array( 'jquery' ), '', true );

}
// Create a file named say, wc-js.js in child theme’s js directory (create if not existing) having the following:

jQuery(function( $ ){

	$( "#menu-product-categories li:has(ul)" ).addClass( "menu-item-has-children" );

});
https://sridharkatakam.com/how-to-conditionally-replace-menu-in-primary-navigation-with-product-categories-and-their-terms-on-woocommerce-pages-in-genesis/

While it is straight forward to manually add WooCommerce Product Categories and their terms as menu items and sub menu items of a custom menu in WordPress, in this article I show how we can set up a custom menu to automatically show all Product Categories and the corresponding terms as sub menus. Additionally we shall replace a menu assigned to Primary Navigation Menu theme location with our “Product Categories” menu on all WooCommerce pages and add automatic sub menu indicators using Font Awesome.
References:

https://codex.wordpress.org/Function_Reference/wp_nav_menu

http://jamescollings.co.uk/docs/v1/jc-submenu/actions-filters/jcsitem_classes/

https://docs.woothemes.com/document/conditional-tags/

https://sridharkatakam.com/adding-nav-sub-menu-indicators-genesis-using-font-awesome/

http://stackoverflow.com/a/11751824/778809

https://sridharkatakam.com/conditionally-assigning-different-menus-in-secondary-navigation-menu-location-in-genesis/
.woocommerce .genesis-nav-menu > .menu-item.menu-item-has-children > a:after {
	content: "\f107";
	font-family: 'FontAwesome';
	font-size: 12px;
	font-size: 1.2rem;
	padding-left: 5px;
	speak: none;
}

.woocommerce ul.sub-menu li.menu-item-has-children > a:after {
	content: "\f105";
	font-family: 'FontAwesome';
	font-size: 12px;
	font-size: 1.2rem;
	padding-left: 10px;
	speak: none;
}

.woocommerce .nav-primary .genesis-nav-menu a:hover,
.woocommerce .nav-primary .genesis-nav-menu .sub-menu a:hover {
	text-decoration: none;
}

/* --- That’s it! --- */
Step 1

Install and activate JC Submenu plugin.
Step 2

At Appearance > Menus create a new menu named Product Categories.

Add any menu item (of any kind), expand it, tick JC Submenu - Automatically populate submenu and Replace Current item with Populated Items. Then select product_cat from the Taxonomies list.

In my test site, I added a Product Category from the left side accordion and configured it.

Navigation Label text does not matter and can be any.