WordPress passing logout URL to menu item not resolving correctly

EDIT:
Adding the following to the code below:

alert(LogoutURL);

shows the URL is coming across to the JS variable incorrectly. Is seems to be “encoded” once passed to the JS var.

Read More

I know this from executing in my PHP the following:

<?php echo wp_logout_url('/') ?>

as this writes the correct URL to the page. Any help is appreciated. Thanks


I am sure this one is straightforward but I have not been able to find how to do this. Maybe I have asked the question wrong… I am trying to insert the “logout with no confirmation” link in WordPress but the URL I pass the menu does not resolve correctly. The menu is part of a theme so I cannot easily modify it.

As such I am using a combination of JS and PHP to generate the link for the current logged in user, by changing the “href” in the “a” item containing “Logout” text, to the output of “wp_logout_url” as follows:

<script type="text/javascript"> 
jQuery( document ).ready(function() {
    /*** change Logout URL if logged in ***/
    var LogoutURL = "<?php echo wp_logout_url('/') ?>";
    jQuery('a').filter(function(index) { return jQuery(this).text() === "Logout"; }).attr("href", LogoutURL);

My resolved menu code:

<li id="menu-item-5516" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-5516">
<a href="http://www.myurl.com/wp-login.php?action=logout&amp;amp;redirect_to=%2F&amp;amp;_wpnonce=1585cbffcc">Logout</a>
</li>

When the JS inserts the resolved URL it seems to add “amp;” to it in places where it found “&”. I even tried without success to use “encodeURI()” function.

How can I pass the URL to the HREF “as is”?

Related posts

Leave a Reply

3 comments

  1. The issue seems to be that wp_logout_url is correctly changing & to &, and then jQuery must be again changing & to & resulting in &amp.

    The hacky solution is to simply do

    jQuery('a').filter(function(index) { return jQuery(this).text() === "Logout"; })
    .attr("href", LogoutURL.split("&amp;amp;").join("&amp;"));
    

    Also, if you parent li elements id doesn’t change, it would be far more efficient to do

    $("#menu-item-5516").find("a").attr("href", ...);
    

    Rather than run a filter on all of the a elements. If not I would still find a better way to select that element, checking every link in the document is overkill.

    Note: You SHOULD have one amp; after every & in a link. That is CORRECT. If you DON’T want that, you can do

    jQuery('a').filter(function(index) { return jQuery(this).text() === "Logout"; })
    .attr("href", LogoutURL.split("&amp;amp;").join("&"));
    
  2. Well this did it… still not sure why this is required. Am I pulling into the JS the url incorrectly?

    var LogoutURL = "<?php echo wp_logout_url('/') ?>";
    jQuery('a').filter(function(index) { return jQuery(this).text() === "Logout"; }).attr("href", LogoutURL.replace(/&amp;/g, "&"));
    
  3. This is my solution to place a logout link in my menu’s list item with class “logout”. The link now carries me through to the login page without the “oops … do you really want to logout?”:

    PHP – replacing &amp; with &:

    $logouturl = str_replace('&amp;','&',wp_logout_url(home_url() . "/wp-login.php?loggedout=true"));
    

    jQuery – replacing href in li.logout a:

    logoutUrl = '<?php echo $logouturl; ?>';
    jQuery('li.logout a').attr('href',logoutUrl);