Logout link in the main navigation menu (without additional query)

Logout-Link ohne Bestätigung - Screenshot/Montage: T.Bortels/cpu20.de

On some WordPress sites, you want users to log in to access certain content. There are also nice and elegant solutions for logging in – it’s only when logging out that it sometimes gets a bit messy. The user is usually redirected to a page with an additional query and asked again whether he/she really wants to log out. In terms of user-friendliness, this is not ideal – the UX could look better. For example: one click on “Logout” – and you are logged out – the logout is complete.

The problem seemed relatively trivial to me at first. On closer inspection, however, the solution turns out to be a little more complex than initially hoped. In the end, all you need is an appropriate plugin and a few lines of additional PHP code in functions.php – and you can log out with just one click. Here is my solution:

First, we need the plugin “If Menu – Visibility control for Menu Items” or a similar plugin to control which menu items are visible to logged-in users and which are visible to unlogged-in users. After all, we only want to display the logout link for registered users – unregistered users, on the other hand, are shown the login link.

Logout-Menu WordPress

Screenshot “if menu” by T.Bortels/cpu20.de

The plugin is quickly installed and configured – in the menu settings there is now the option to display or hide individual menu links according to predefined conditions. In this case, we use the option to display the logout link only for registered users. Accordingly, we only display the login link for users who are not logged in.

Now we just have to customize the link – this can be done via the functions.php

I found the following suggestion on Stackexchange :

add_action('check_admin_referer', 'logout_without_confirm', 10, 2);
function logout_without_confirm($action, $result)
{
    /**
     * Allow logout without confirmation
     */
    if ($action == "log-out" && !isset($_GET['_wpnonce'])) {
        $redirect_to = isset($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : 'url-you-want-to-redirect';
        $location = str_replace('&', '&', wp_logout_url($redirect_to));
        header("Location: $location");
        die;
    }
}

Unfortunately, this did not work as it should. I’m not sure exactly what the problem is – the user was still redirected to the confirmation page after clicking on “Logout”, but the approach was quite right: to supplement the existing logout link so that a new confirmation would be skipped.

Then I found the following solution on Github:

// LOGOUT LINK IN MENU
function diww_menu_logout_link( $nav, $args ) {
  $logoutlink = '<li><a href="'.wp_logout_url().'">Logout</a></li>';
  if( $args->theme_location == 'primary' ) {
    return $nav.$logoutlink ;
  } else {
    return $nav;
  }
}
add_filter('wp_nav_menu_items','diww_menu_logout_link', 10, 2);

Much more compact – but this function supplements the menu (in this case “primary”) with an additional logout link.

Both approaches combined gave me the right result:

function change_menu($items){
  foreach($items as $item){
    if( $item->title == "Logout"){
      $item->url = wp_logout_url();
    }
  }
  return $items;
}
add_filter('wp_nav_menu_objects', 'change_menu');

The function searches for a menu item with the title “Logout” and then sets the link for this menu item to the direct Lougout address. And Bob’s your oncle.