wp_logout_url()…. AGH!!!

So I’m working on a site right now that incorporates the new bbPress plugin with WordPress. I’m testing the login/logout process, and since it’s now a plugin (instead of a standalone) you can use your WordPress logging for both things (the site and the forum).

So I’m putting in a link for the logout url, via wp_logout_url(), and I’m following the Codex instructions for the redirect. but as I continue testing, I realize that the redirect isn’t working. Hmm. So off to the forums I trot.

And discover that this isn’t a new issue.


So I start picking things apart. After a gazillion times of logging in and out, I realize a single weird thing: when I log out, it’s adding in a new directory. So this is why none of my code is working, and why it keeps going to a 404 page. (Let me ‘splain, Lucy.)

The site url is http://localhost:8888/somesite.

When I log out – well first off, it’s completely ignoring the redirect, and redirecting to the page you’re already on. Doesn’t matter if you’re using get_bloginfo(‘home’); or home_url(), or site_url() in there – even if you hand-code the home URL (or any other URL for that matter) in there, it’s ignored. What it ends up doing is, when you log out, the URL it redirects to is this (assuming the page you’re on when you log out is “somepage”):

The site url is http://localhost:8888/somesite/somesite/somepage?loggedout=true

It took me a few times to realize that “somesite” was being put in there twice. Well no freaking wonder it wasn’t working.

So of course I did what I always do. I could have put in a hack and hard-coded the link (or other methods), but the wp_nonce_url would not be there, and I’m a safety gal. So after about 20 minutes of logging in and logging out after each code tweak, I found a solution.

I present it to you.

The original function in WordPress core (in wp-includes/general-template.php) is like so:

1
2
3
4
5
6
7
8
9
10
11
function wp_logout_url($redirect = '') {
    $args = array( 'action' => 'logout' );
    if ( !empty($redirect) ) {
        $args['redirect_to'] = urlencode( $redirect );
    }

    $logout_url = add_query_arg($args, site_url('wp-login.php', 'login'));
    $logout_url = wp_nonce_url( $logout_url, 'log-out' );

    return apply_filters('logout_url', $logout_url, $redirect);
}

After major tweaking, I found that the last line is causing the problem. Remove it, and pop it outside the function, and it works like it’s supposed to. So if core were like this:

1
2
3
4
5
6
7
8
9
10
11
12
apply_filters('logout_url', 'wp_logout_url')
        function wp_logout_url($redirect = '') {
    $args = array( 'action' => 'logout' );
    if ( !empty($redirect) ) {
        $args['redirect_to'] = urlencode( $redirect );
    }

    $logout_url = add_query_arg($args, site_url('wp-login.php', 'login'));
    $logout_url = wp_nonce_url( $logout_url, 'log-out' );

    return $logout_url;
}

it works a treat.

Now I’m never one to recommend editing core. Never never never. But when you have an issue like this, you can basically just do it anew in your functions.php file (within your theme), and if the WP devs fix it (or not) you never have to worry about losing the fix. So if you rename the function above and pop it into your functions.php file, then you’ll be all set. i.e.:

1
2
3
4
5
6
7
8
9
10
11
12
apply_filters('logout_url', 'my_fixed_wp_logout_url')
        function my_fixed_wp_logout_url($redirect = '') {
    $args = array( 'action' => 'logout' );
    if ( !empty($redirect) ) {
        $args['redirect_to'] = urlencode( $redirect );
    }

    $logout_url = add_query_arg($args, site_url('wp-login.php', 'login'));
    $logout_url = wp_nonce_url( $logout_url, 'log-out' );

    return $logout_url;
}

Then, wherever you were planning to use wp_logout_url(), use my_fixed_wp_logout_url() instead. Yay!

Comments

  • David says:

    Great post, but I have a little question.

    In the second of code where it has:

    function wp_logout_url($redirect = ”)

    In the parameters it has an assignment instead of a variable, why? (I’m sort of a nooby in JavaScript myself).

  • lån, alex says:

    Hey. Great tip thanks! Would love to see WP update core tho since i really dont like messing with it in case i forget to fix it again after i update or smth.

  • Tung says:

    Having the same problem, but with BuddyPress. Glad someone figured it out before I had to digg into the code!

  • Shelly says:

    David – sorry it took so long to get back to you on your question. Been crazy busy here.

    First off, it’s PHP, not Javascript.

    Secondly, the “function wp_logout_url($redirect=”)” line sets up the function, where a variable ($redirect) defaults to nothing. That way, if the function is used with no input given as a value for $redirect, it won’t throw up an error that a required parameter is missing.

    wp_logout_url(), anyway, is WordPress core, not the fixed function. So if you want any more explanation than that, you’d probably have to contact the WordPress dev team for why they chose to do it that way. But the most likely reason is what I have above – so you can have a defined variable (for use elsewhere) and the definition of that variable – by default – is nothing.

  • Shelly says:

    And Alex, that’s why I recommended NOT changing core, and simply placing this fix in your functions.php. You should never mess with core. but when you have to, this is the proper way to do it.

  • Susie says:

    This is great and really well documented. Easy to figure out by someone who is new to WordPress. Unfortunately, when I added the code via Theme Editor in wp-admin, I couldn’t get to my site or the administration of the site anymore. I had to remove the code outside WordPress and then I could get to it again. Any ideas?

    Thanks in advance.

    • Shelly says:

      Yeah, I wouldn’t recommend using the Theme Editor to add code. If you copy/paste, and say miss a closing tag or bracket, it’ll turn your site into a “blank white page” until you remove the offending oopsie. My guess is, that’s what happened: you copied the code directly from the site, and missed a closing bracket or something (or maybe even the first letter in the function – I do stuff like that all the time). That’s all it takes.

      But really, without knowing what error you were getting, I can only guess. If your site isn’t set to show error messages, then you’d actually have to look at your server’s error logs to know what, exactly, was the issue. But I’m giving my best guess.

  • Have your say: