admin管理员组文章数量:1122846
I have a custom menu on a wordpress + woocommerce site using the Walker_Nav_Menu class. When hiding posts (products) from the site those posts and category are still included in the custom menu. I would like to know how to remove either the specific product posts from this menu, for e.g. post ID = 6927 - or to remove the category (and the products therein) from this menu, for e.g. category ID = 41.The category I want to hide is "End of range" in this image:
I have tried many solutions over the past 2 days without success:
1)
function wpse31748_exclude_menu_items( $items, $menu, $args ) {
// Iterate over the items to search and destroy
foreach ( $items as $key => $item ) {
if ( $item->object_id == 6927 ) unset( $items[$key] );
}
return $items;
}
add_filter( 'wp_get_nav_menu_items', 'wpse31748_exclude_menu_items', null, 3 );
and different variations of above.
I'm not sure if I'm completely off track but I thought updating the file template-parts/modules/module-category-menu.php to exclude the category may work, here is the contents of that file:
<?php
$orderby = 'date';
$order = 'desc';
$hide_empty = true ;
$cat_args = array(
'orderby' => $orderby,
'order' => $order,
'hide_empty' => $hide_empty,
);
$product_categories = get_terms( 'product_cat', $cat_args );
if( !empty($product_categories)) :
?>
<div class="row">
<div class="col-12 sec-menu">
<ul class=" nav nav-justified" id="sec-menu">
<?php
foreach ($product_categories as $key => $category):
?>
<li class="nav-item">
<h2>
<a class="nav-link collapsed top-menu" href="#cat<?php echo $category->term_id; ?>" data-toggle="collapse" data-target="#cat<?php echo $category->term_id; ?>">
<?php echo $category->name; ?>
</a>
</h2>
<?php
$args = array(
'posts_per_page' => '-1',
'post_type' => 'product',
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'asc',
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'terms' => array($category->term_id),
'operator' => 'IN'
),
)
);
$products = new WP_Query($args);
if($products->have_posts()):
?>
<div class="collapse sub-menu" id="cat<?php echo $category->term_id; ?>" aria-expanded="false" data-parent="#sec-menu">
<ul class="flex-column nav">
<?php
while($products->have_posts()):
$products->the_post();
?>
<li class="nav-item">
<a class="nav-link sub-link" href="<?php the_permalink();?>" title="<?php the_title(); ?>">
<span><?php the_title(); ?></span>
</a>
</li>
<?php
endwhile;
wp_reset_query();
?>
</ul>
</div>
<?php
endif;
?>
</li>
<?php
endforeach;
?>
</ul>
</div>
</div>
<?php
endif;
?>
Any help is greatly appreciated.
EDIT Here is the Walker_Nav_Menu class from the functions.php file:
class Custom_Foundation_Nav_Menu extends Walker_Nav_Menu
{
private $curItem;
function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output)
{
$element->hasChildren = isset($children_elements[$element->ID]) && !empty($children_elements[$element->ID]);
return parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output);
}
function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0)
{
global $wp_query;
$new_class = array();
$this->curItem = $item;
$indent = ($depth) ? str_repeat("\t", $depth) : '';
$class_names = $value = '';
$classes = empty($item->classes) ? array() : (array) $item->classes;
$new_class[] = 'nav-item';
if (in_array('current-menu-item', $classes) || in_array('current-menu-ancestor', $classes)) {
$new_class[] = 'active';
}
if ($item->hasChildren) {
$add_sub_class = 'nav-link collapsed';
} else {
$add_sub_class = 'nav-link';
}
if ($depth > 0) {
$add_sub_class .= ' sub-link ';
}
$new_class = implode(' ', $new_class);
// echo $new_class;
$class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item));
$class_names = ' class="' . $new_class . ' ' . $class_names . '"';
$class_names = trim($class_names);
$output .= $indent . '<li id="menu-item-' . $item->ID . '" ' . $value . $class_names . '>';
$attributes = !empty($item->attr_title) ? ' title="' . esc_attr($item->attr_title) . '" ' : '';
if ($item->hasChildren && !is_page(6927)) {
$attributes .= ' href="#submenu' . $item->ID . '" ';
$attributes .= ' data-toggle="collapse" ';
$attributes .= ' data-target="#submenu' . $item->ID . '" ';
} else {
$attributes .= !empty($item->url) ? ' href="' . esc_attr($item->url) . '" ' : '';
}
$attributes .= !empty($add_sub_class) ? ' class="' . $add_sub_class . '" ' : '';
$item_output = $args->before;
$item_output .= '<a' . $attributes . ' ><span data-hover="' . $args->link_before . apply_filters('the_title', $item->title, $item->ID) . '">';
$item_output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID);
$item_output .= '</span></a>';
$item_output .= $args->after;
$output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
}
function start_lvl(&$output, $depth = 0, $args = array())
{
global $wp_query;
$thisItem = $this->curItem;
$indent = str_repeat("\t", $depth);
$output .= "\n$indent<div class='collapse' id='submenu$thisItem->ID' aria-expanded='false'><ul id='submenu-$thisItem->ID' class='flex-column nav sub-nav'>\n";
}
}
I have a custom menu on a wordpress + woocommerce site using the Walker_Nav_Menu class. When hiding posts (products) from the site those posts and category are still included in the custom menu. I would like to know how to remove either the specific product posts from this menu, for e.g. post ID = 6927 - or to remove the category (and the products therein) from this menu, for e.g. category ID = 41.The category I want to hide is "End of range" in this image:
I have tried many solutions over the past 2 days without success:
1)
function wpse31748_exclude_menu_items( $items, $menu, $args ) {
// Iterate over the items to search and destroy
foreach ( $items as $key => $item ) {
if ( $item->object_id == 6927 ) unset( $items[$key] );
}
return $items;
}
add_filter( 'wp_get_nav_menu_items', 'wpse31748_exclude_menu_items', null, 3 );
and different variations of above.
I'm not sure if I'm completely off track but I thought updating the file template-parts/modules/module-category-menu.php to exclude the category may work, here is the contents of that file:
<?php
$orderby = 'date';
$order = 'desc';
$hide_empty = true ;
$cat_args = array(
'orderby' => $orderby,
'order' => $order,
'hide_empty' => $hide_empty,
);
$product_categories = get_terms( 'product_cat', $cat_args );
if( !empty($product_categories)) :
?>
<div class="row">
<div class="col-12 sec-menu">
<ul class=" nav nav-justified" id="sec-menu">
<?php
foreach ($product_categories as $key => $category):
?>
<li class="nav-item">
<h2>
<a class="nav-link collapsed top-menu" href="#cat<?php echo $category->term_id; ?>" data-toggle="collapse" data-target="#cat<?php echo $category->term_id; ?>">
<?php echo $category->name; ?>
</a>
</h2>
<?php
$args = array(
'posts_per_page' => '-1',
'post_type' => 'product',
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'asc',
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'terms' => array($category->term_id),
'operator' => 'IN'
),
)
);
$products = new WP_Query($args);
if($products->have_posts()):
?>
<div class="collapse sub-menu" id="cat<?php echo $category->term_id; ?>" aria-expanded="false" data-parent="#sec-menu">
<ul class="flex-column nav">
<?php
while($products->have_posts()):
$products->the_post();
?>
<li class="nav-item">
<a class="nav-link sub-link" href="<?php the_permalink();?>" title="<?php the_title(); ?>">
<span><?php the_title(); ?></span>
</a>
</li>
<?php
endwhile;
wp_reset_query();
?>
</ul>
</div>
<?php
endif;
?>
</li>
<?php
endforeach;
?>
</ul>
</div>
</div>
<?php
endif;
?>
Any help is greatly appreciated.
EDIT Here is the Walker_Nav_Menu class from the functions.php file:
class Custom_Foundation_Nav_Menu extends Walker_Nav_Menu
{
private $curItem;
function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output)
{
$element->hasChildren = isset($children_elements[$element->ID]) && !empty($children_elements[$element->ID]);
return parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output);
}
function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0)
{
global $wp_query;
$new_class = array();
$this->curItem = $item;
$indent = ($depth) ? str_repeat("\t", $depth) : '';
$class_names = $value = '';
$classes = empty($item->classes) ? array() : (array) $item->classes;
$new_class[] = 'nav-item';
if (in_array('current-menu-item', $classes) || in_array('current-menu-ancestor', $classes)) {
$new_class[] = 'active';
}
if ($item->hasChildren) {
$add_sub_class = 'nav-link collapsed';
} else {
$add_sub_class = 'nav-link';
}
if ($depth > 0) {
$add_sub_class .= ' sub-link ';
}
$new_class = implode(' ', $new_class);
// echo $new_class;
$class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item));
$class_names = ' class="' . $new_class . ' ' . $class_names . '"';
$class_names = trim($class_names);
$output .= $indent . '<li id="menu-item-' . $item->ID . '" ' . $value . $class_names . '>';
$attributes = !empty($item->attr_title) ? ' title="' . esc_attr($item->attr_title) . '" ' : '';
if ($item->hasChildren && !is_page(6927)) {
$attributes .= ' href="#submenu' . $item->ID . '" ';
$attributes .= ' data-toggle="collapse" ';
$attributes .= ' data-target="#submenu' . $item->ID . '" ';
} else {
$attributes .= !empty($item->url) ? ' href="' . esc_attr($item->url) . '" ' : '';
}
$attributes .= !empty($add_sub_class) ? ' class="' . $add_sub_class . '" ' : '';
$item_output = $args->before;
$item_output .= '<a' . $attributes . ' ><span data-hover="' . $args->link_before . apply_filters('the_title', $item->title, $item->ID) . '">';
$item_output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID);
$item_output .= '</span></a>';
$item_output .= $args->after;
$output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
}
function start_lvl(&$output, $depth = 0, $args = array())
{
global $wp_query;
$thisItem = $this->curItem;
$indent = str_repeat("\t", $depth);
$output .= "\n$indent<div class='collapse' id='submenu$thisItem->ID' aria-expanded='false'><ul id='submenu-$thisItem->ID' class='flex-column nav sub-nav'>\n";
}
}
Share
Improve this question
edited Apr 10, 2020 at 9:26
MarvynH
asked Apr 9, 2020 at 13:19
MarvynHMarvynH
34 bronze badges
3
- are you using wp_nav_menu() to output the menu? did you supply any $args? if so, what is the $args? You have mentioned about the Walker_Nav_Menu but there seems no related code for using this other than the filter. – 西門 正 Code Guy - JingCodeGuy Commented Apr 10, 2020 at 1:16
- @simongcc I've edited my question to add in the code for the Walker_Nav_Menu from the functions.php file. – MarvynH Commented Apr 10, 2020 at 9:27
- I have shared some way for you to try. If you haven't tried these methods, you may give it a try first. Because they are too long as a comment. So I post it as answer. – 西門 正 Code Guy - JingCodeGuy Commented Apr 10, 2020 at 9:57
2 Answers
Reset to default 0I am still not sure how you call the menu or what $args you supply for the menu. But could suggest you some way to figure it out.
first test: return an empty array, if menu becomes empty, the filter is running,
if not, then your filter is not running and need to find another way
function wpse31748_exclude_menu_items( $items, $menu, $args ) {
return [];
}
add_filter( 'wp_get_nav_menu_items', 'wpse31748_exclude_menu_items', null, 3 );
assume the filter is running, then probably your test logic have problem
function wpse31748_exclude_menu_items( $items, $menu, $args ) {
// Iterate over the items to search and destroy
$found_key = null;
foreach ( $items as $key => $item ) {
if ( $item->object_id == 6927 ) {
// unset( $items[$key] ); // unset a iterating array is not a good idea and may lead to bug sometimes
$found_key = $key; // handle it later.
}
}
var_dump($found_key); // make sure you find something
var_dump($items); // to compare before and after removal if it found something
unset( $items[$found_key] );
var_dump($items);
return $items;
}
add_filter( 'wp_get_nav_menu_items', 'wpse31748_exclude_menu_items', null, 3 );
I've resolved this by editing the $cat_args array to exclude the category IDs I don't want shown in any menu (in below e.g. 34 is the category ID) - the file in my case was in a 'modules' folder:
<?php
$orderby = 'date';
$order = 'desc';
$hide_empty = true ;
$cat_args = array(
'orderby' => $orderby,
'order' => $order,
'hide_empty' => $hide_empty,
'exclude' => '34',
);
Category is removed from the menu but the specific posts can still be accessed and linked to with direct linking.
本文标签: categoriesHow to remove an item from a custom WalkerNavMenu
版权声明:本文标题:categories - How to remove an item from a custom Walker_Nav_Menu 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736283049a1926840.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论