If you have control over the the wp_nav_menu()
call, you can implement a custom Walker_Nav_Menu
class for fine-grained control over the rendering of an array of nav menu items to HTML.
If the markup of the items you wish to add is the same as that which the default Walker_Nav_menu
already produces, you can use a 'wp_get_nav_menu_items'
filter hook in order to add "virtual nav menu item" objects to the array before they are processed into HTML:
/**
* Add a login/logout link to the nav menu in the `primary` location, as a child
* of a menu item for a Page with the slug `members` (if present).
*
* @see https://wordpress.stackexchange.com/a/390893/25324
*
* @param WP_Post[] $items The WP_Post objects representing menu items in this menu.
* @param WP_Term $menu The WP_Term object representing this menu.
* @param array $args The arguments used to retrieve menu items associated with this menu.
* @return array The filtered $items array.
*/
function wpse390890_insert_primary_nav_login_link( $items, $menu, $args ) {
if( is_admin() )
return $items;
// Bail out if this menu isn't `primary` or `primary` is being loaded in the dashboard.
if( $menu->slug !== 'primary' || is_admin() )
return $items;
// Find the ID of the Page with the slug `members` in the menu items.
foreach( $items as $item ) {
if( $item->post_type !== 'page' || $item->post_name !== 'members' )
continue;
$members_page_id = $item->ID;
break;
}
// Bail if the `members` page is not in this menu.
if( ! isset( $members_page_id ) )
return $items;
$logged_in = is_user_logged_in();
$link_title = __( $logged_in ? 'Log In' : 'Log Out', 'wpse390890' );
// Insert a new WP_Post object for the link.
$items[] = new WP_Post(
(object) [
'ID' => 'user-login',
'menu_item_parent' => $members_page_id,
'classes' => [ 'member-auth-link' ],
'type' => 'virtual',
'object' => 'virtual',
'title' => $link_title,
'attr_title' => $link_title,
'url' => $logged_in ? wp_logout_url() : wp_login_url(),
]
);
return $items;
}
add_filter( 'wp_get_nav_menu_items', 'wpse390890_insert_primary_nav_login_link', 10, 3 );
See wp_setup_nav_menu_item()
's implementation for hints on which fields to specify, and how WP_Post
objects are converted into objects representing nav menu items. var_dump()
ing $items
in the filter above is also a good way to explore the format and properties of the items which are already in the menu.