Using WordPress ‘pre_wp_nav_menu’ PHP filter

‘pre_wp_nav_menu’ is a WordPress filter that can be used to short-circuit the wp_nav_menu() output.

By returning a non-null value from the filter, you can bypass the default menu generation process and return or echo a custom output based on the provided arguments.

Usage

add_filter('pre_wp_nav_menu', 'my_custom_menu_output', 10, 2);
function my_custom_menu_output($output, $args) {
    // Your custom code here.
    return $output;
}

Parameters

  • $output (string|null): Nav menu output to short-circuit with. Default null.
  • $args (stdClass): An object containing wp_nav_menu() arguments.

Examples

Remove a specific menu item

add_filter('pre_wp_nav_menu', 'remove_specific_menu_item', 10, 2);
function remove_specific_menu_item($output, $args) {
    if ($args->theme_location == 'primary') {
        // Find and remove specific menu item.
        $output = preg_replace('/<li[^>]*><a href="[^"]*page-to-remove[^"]*"[^>]*>[^<]*</a></li>/', '', $output);
    }
    return $output;
}

This code removes a menu item with the URL “page-to-remove” from the primary menu location.

add_filter('pre_wp_nav_menu', 'add_login_logout_link', 10, 2);
function add_login_logout_link($output, $args) {
    if ($args->theme_location == 'primary') {
        $link = is_user_logged_in() ? wp_logout_url() : wp_login_url();
        $text = is_user_logged_in() ? 'Logout' : 'Login';
        $output .= '<li><a href="' . $link . '">' . $text . '</a></li>';
    }
    return $output;
}

This code adds a login or logout link to the primary menu based on the user’s login status.

Add a search form to the menu

add_filter('pre_wp_nav_menu', 'add_search_form_to_menu', 10, 2);
function add_search_form_to_menu($output, $args) {
    if ($args->theme_location == 'primary') {
        $search_form = get_search_form(false);
        $output .= '<li class="menu-search">' . $search_form . '</li>';
    }
    return $output;
}

This code adds a search form to the primary menu.

Display a custom message for empty menus

add_filter('pre_wp_nav_menu', 'display_empty_menu_message', 10, 2);
function display_empty_menu_message($output, $args) {
    if (empty($output)) {
        $output = '<li class="menu-empty">No menu items available.</li>';
    }
    return $output;
}

This code displays a custom message “No menu items available” when a menu is empty.

Add a custom CSS class to the first menu item

add_filter('pre_wp_nav_menu', 'add_first_menu_item_class', 10, 2);
function add_first_menu_item_class($output, $args) {
    $output = preg_replace('/<li/', '<li class="first-menu-item"', $output, 1);
    return $output;
}

This code addsa custom CSS class “first-menu-item” to the first menu item in the menu. This can be used to style the first menu item differently from the rest of the menu items.

Highlight the current menu item with a custom CSS class

add_filter('pre_wp_nav_menu', 'highlight_current_menu_item', 10, 2);
function highlight_current_menu_item($output, $args) {
    global $post;
    if (is_single() || is_page()) {
        $output = preg_replace('/<li(.*?)class="([^"]*?)"><a href="' . get_permalink($post->ID) . '"/', '<li$1class="$2 current-menu-item"><a href="' . get_permalink($post->ID) . '"', $output);
    }
    return $output;
}

This code adds a custom CSS class “current-menu-item” to the current menu item when viewing a single post or page. This allows you to style the current menu item differently to indicate which page or post the user is currently viewing.

Add an icon to a specific menu item

add_filter('pre_wp_nav_menu', 'add_icon_to_specific_menu_item', 10, 2);
function add_icon_to_specific_menu_item($output, $args) {
$icon_html = '<i class="fas fa-home"></i> ';
$output = preg_replace('/<li[^>]*><a href="[^"]*page-with-icon[^"]*"[^>]*>[^<]*</a></li>/', '<li><a href="page-with-icon">' . $icon_html . 'Page with Icon</a></li>', $output);
return $output;
}

This code adds an icon (using Font Awesome in this example) to a specific menu item with the URL “page-with-icon”. Replace the page-with-icon URL and $icon_html variable with the appropriate values for your use case.