I am using the following hook to loop over my menu items and apply a class based on certain criteria.

add_filter( 'nav_menu_css_class', 'highlight_base_category', 1, 3 );

The nav_menu_css_class filter runs for each individual menu item, but I want to completely halt the filter once the class has been applied to one menu item, to prevent more than one menu item having the same class.

I've been looking at setting a global boolean, or using a session, but it seems messy.

Is there a way of breaking out of the filter for the entirety of the current page request, or a global flag i could set and check each time a menu item is filtered?


Yes, there is such way. All you need to do is to unregister your filter inside it:

function highlight_base_category( $classes, $item, $args ) {
    // most probably you have some if statement here
    if ( /* YOU CONDITION */ ) { 
        // your code
        remove_filter( 'nav_menu_css_class', 'highlight_base_category', 1 );
    return $classes;
add_filter( 'nav_menu_css_class', 'highlight_base_category', 1, 3 );
  • how is this any different than the previous answer by Chris J Allen? Jun 5 '18 at 18:45
  • It's full answer, not just one-liner that doesn't show the usage. Also it uses remove_filter in correct way. Jun 5 '18 at 18:47

Looks like I just remove said filter, then it'll get reattached on the next page request.

// if matched...
remove_filter( 'nav_menu_css_class', 'highlight_base_category', 1, 3 );
  • 1
    remove_filter() only takes 3 arguments. The 3 is unnecessary. Jun 5 '18 at 16:23

In addition to the answer by Chris J Allen, if you want to remove all filters including those not added by your plugin/theme, you would use remove_all_filters() instead of remove_filter().

add_filter( 'nav_menu_css_class', 'wpse_nav_menu_css_class', 1, 4 );
function wpse_nav_menu_css_class( $classes, $item, $args, $depth ) {
  //* Do something useful to the nav menu CSS class
  $classes[] = 'highlight';

  //* Make sure no other filters modify the classes
  remove_all_filters( 'nav_menu_css_class' );
  return $classes;
  • You may continue this discussion in chat. The fact is that any developer should use any code on this site at their own risk.This is not a piece of code that will break a website, it just does exactly as it says which is removes all filters of a specific type. Keep it civil please.
    – Howdy_McGee
    Jun 5 '18 at 20:37

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.