wp_nav_menu() loses 'current-menu-*' classes on single product page within category
Вопрос
I have my menu set up like so:
- Shop Online (WPeC 'Products Page' page)
- Product Category (WPeC Category)
- Product Category (WPeC Category)
- Product Sub Category (WPeC Category)
- Product Sub Category (WPeC Category)
- ...
Single product pages are viewable from any category or sub category page as they both show the product listing view.
Now when I select either Shop Online, a product category or sub-category the menu updates it's CSS classes to match the current hierachy with the usual (example) current-menu-page
, current-menu-ancestor
and current-menu-parent
among others. It doesn't matter if I click on the menu or the category listing on the Shop Online page to get there.
For some reason as soon as I view a product singularly (domain.tld/product-cat/sub-cat/product-single
or domain.tld/product-cat/product-single
), the menu classes are removed and I lose my menu highlighting because the classes are no longer there.
Is there a way that I can reflect the single product view in the menu by highlighting the current category/ies that the product is in, as well as the Shop Online
menu item/link respective of how you got to the product?
WP v3.5
WPeC v3.8.9.4
Решение
Looking for a solution for the same problem, I came across this:
add_filter( 'nav_menu_css_class', 'add_parent_url_menu_class', 10, 2 );
function add_parent_url_menu_class( $classes = array(), $item = false ) {
// Get current URL
$current_url = current_url();
// Get homepage URL
$homepage_url = trailingslashit( get_bloginfo( 'url' ) );
// Exclude 404 and homepage
if( is_404() or $item->url == $homepage_url ) return $classes;
if ( strstr( $current_url, $item->url) ) {
// Add the 'parent_url' class
$classes[] = 'parent_url';
}
return $classes;
}
function current_url() {
// Protocol
$url = ( 'on' == $_SERVER['HTTPS'] ) ? 'https://' : 'http://';
$url .= $_SERVER['SERVER_NAME'];
// Port
$url .= ( '80' == $_SERVER['SERVER_PORT'] ) ? '' : ':' . $_SERVER['SERVER_PORT'];
$url .= $_SERVER['REQUEST_URI'];
return trailingslashit( $url );
}
Hope it helps!
Другие советы
If you are using Woocommerce plugin you can add class like this
if (
($post->post_type == 'product') &&
($item->object_id == get_option('woocommerce_shop_page_id'))
) {
array_push($classes, 'current-page-ancestor');
}
How To Get WooCommerce Page IDs
get_option( 'woocommerce_shop_page_id' );
get_option( 'woocommerce_cart_page_id' );
get_option( 'woocommerce_checkout_page_id' );
get_option( 'woocommerce_pay_page_id' );
get_option( 'woocommerce_thanks_page_id' );
get_option( 'woocommerce_myaccount_page_id' );
get_option( 'woocommerce_edit_address_page_id' );
get_option( 'woocommerce_view_order_page_id' );
get_option( 'woocommerce_terms_page_id' );
Feels like a bit of a hack, but I ended up using this CSS solution. Took about 5 minutes instead of spending hours trying to figure out how to add .current-menu-ancestor
into the menu walker with PHP.
Please note that this is a good solution for a custom theme or plugin that is only for one site. Obviously using a specific menu ID doesn't create a general solution that could be used in a theme for the Wordpress.org marketplace, etc.
Original CSS:
.current-menu-item > a,
.current-menu-ancestor > a {
color: #000;
}
New CSS:
.current-menu-item > a,
.current-menu-ancestor > a,
.woocommerce-page #menu-item-1234 > a /* add your own Store menu item ID here */
{
color: #000;
}
The woocommerce-page
body class covers:
- store home
- store taxonomy archives
- individual product pages
- cart
- checkout
- probably a bunch of other stuff I'm not thinking of right now
- successfully doesn't target other areas of the site
As explained by a support tech over at getshopped.org:
[sic] is actually a limitation of the WordPress menu system. I am unaware of a way to change this behavior. Possibly you could find a menu plugin and make your menu area a widget where you could add the menu by widget that provides an enhanced menu system.