by Ryan Sutana

  • Really usefull! Thank you very much.

    • Glad you found this helpful

  • AG

    Hi there,
    Might be a noob question, but where do I place each of the sections above?
    I’ve started by creating a new template to hold the custom page, I’m just unsure where everything goes.


  • nick_o_laas

    don’t use this folks, its garbage. and for the record, when copying your code, every single bracket has a slash through it, which is tireless work. be a better coder please, thanks!

    • I don’t know why you find this not useful and other are?, also every single bracket has slash? I really don’t know what you’re talking about, also I already provided the code and I’m using it on my other project if you really wanted to know then you ask and not just commenting don’t my code because it’s FREE anyone can use it can modify it can use in their project and more, and you?

      • icamys

        About brackets: Perhaps it’s a code editors issue. I get the same when I copy your code and paste it anywhere.

        For example my php open tag always looks like “”

        • yeah it’s the syntax highlighter I’m currently using, it might be on my settings page because it seems works on other site with the same code/syntax highlighter.

      • icamys

        By the way, it would be nice to add here the workaround part from your previous tutorial.

        • I actually don’t recommend using the old approach it’s not secure 🙂

          • icamys

            I’m sorry, looks like I wasn’t clear enough. I mean that in this article should also be included the part where the javascript theme_ajax variable is defined 🙂
            I have used your code from this article apart from previous one and run into “undefined variable” error.

          • Oops I’ve added explanation in Workaround area just like my other article, hope that helps 😉

          • icamys

            Thank you for your code. You’ve done a great job!

  • icamys

    Ryan, it seems that in your function reset_pass_callback() is not covered case when both pass1 and pass2 are empty strings. Function just runs but doesn’t execute any actions with users password.

    • Yeah at the moment it simply ignore or didn’t process if user didn’t add any password string, I’ve added a new condition to see if user added some string and return error, hope that helps.

  • Ben

    hi there, just found a small mistake in the theme-ajax.js in lin 47:

    it should be: nonce: this.rs_user_reset_password_nonce.value

    nonce: this.rs_user_reset_password_action.value

    thanks for the nice work.

    • Hi Ben, thanks for pointing that out, didn’t notice that one.

  • chuyqwerty

    I got it to work, but the link I get on the email sends me to the wordpress default page to enter the new password. How do I get it to go to the custom one? I do not know where to put your reset password form…


    • chuyqwerty

      Never mind. I got it working

      • amit mishra

        Can you plz tell me where you put your reset password form bcz i have same problem like you.

        • It’s in PHP code block at line 92

          Hope that helps

          • amit mishra

            thanks for your reply i got it

  • Mathieu

    I think I’ve a bug with the js. Even if theme-ajax.js present in the page, the js function don’t work.
    Maybe it’s because I need to put the wp_enqueue_script in the init? But I’m not sure how do to that.

    • Nope, wp_enqueue_script is itself a hook name so there’s no need to add it into other hook, can you see if you have conflict, etc.?

      • Mathieu

        Well, I’ve the same problem with the showing . This part work now. That is really easy to fix for me. But I don’t know if there similar issue in the javascript that I copy. The js show no error but maybe you can send me the js file by email? to be sure. Thanks for your quick answer.

        • yeah can’t get rid of this annoying PHP tag issue on my current code highlighter, no issue so far for JS, sorry can’t send you code in email, if that the case then it goes to personal and that involve penny, hope you understand.

          Ryan S

          • Mathieu

            Well, if no known issue, so maybe it’s a conflict. Thanks!

  • Ray

    where do i put the php file..the localize script seems to be pulling the default admin ajax?

    • It should be in functions.php file, by default admin-ajax is not called in “front-end” area so what we’re doing it localize the file in front-end area so we can do WP ajax.

      • Ray

        Thanks Ryan..I got it working great now. Best custom reset option I have seen out there while exploring options.

        Only thing i am trying to tweak— If the user links to the custom page from the custom reset key sent in the email…and they are for some reason already logged in..WP throw a pluggable error….”Cannot modify header information – headers already sent”

        Is there anyway to avert this possible error showing up for the user.

        • Hi, checked your tweak code it might be the issue as the above works without any issue 🙂

  • dogstring

    Hmmm…i got it working and im receiving email but when i click the link it redirects me to default wordpress password reset can i redirect this to the custom form?

    • See below comment from @chuyqwerty:disqus, I’ve provided answer in there, hope that helps 😉

  • Ray

    Ryan, have you checked the reset page template lately, it is no longer working on a few sites i have been using it on…i always get the ‘invalidkey’ error

    • Hi @ray didn’t check the code yet in the latest version I’ll look at it when I have spare time.

  • Ray

    Ryan, the WordPress 4.3 Update changed the hashing algorithm…Line 84 of the php will need to be updated to this:
    $hashed = time() . ':' . $wp_hasher->HashPassword( $key )

    That seems to get things closer to working again, however I am still getting double encoding on the rest password links—still working on that.

  • RandomHook

    Hi Ryan,
    Thanks for the great tutorial !!! It is quite clear and makes me understand the logic, it also saves my time.
    I am able to reset password and logged in with new password successfully.
    Just one quick question, with your version, does it remove the attached “key” and “login” info in the url after clicking the reset password link in the mail?
    It removes key and login value if i go to default wordpress reset password page, so I am wondering if I miss something in the code. I just want to make sure whether there is something wrong or not in my code.



    • The idea here is to use our own customize, reset and forgot password so with that idea we create our own custom page template, so there’s no need to use default wp page as we created our own 🙂

      Hope that helps

  • sylverios

    Hi not sure why but it seems clicking reset link says expire?

    • Hi, sorry didn’t notice your concern, I’ve updated the code now to match the new WP version hashing algorithm

      Ryan S


    Hey Ryan ..I followed your code.On clicking email it redirects me to wp-login.php.and when I change your code from $message .= network_site_url(“wp-login.php?action=rp&key=$key&login=” . rawurlencode($user_login), ‘login’) . “rn”;

    $message .= network_site_url(“set-password?action=rp&key=$key&login=” . rawurlencode($user_login), ‘login’) . “rn”;
    (Set password is the page where i want to redirect .But on that page password is not been reset.Although it gives message as ‘password is been reset’ but when i try to login with that password i couldnt that means my password is not been changed.)

    • Check the updated code 🙂

  • Gael GERARD

    Hello, thank you for your code, it is very usefull.

    But, i have a problem in the first form error message.

    When I enter a valid account username or email, the message of confirmation displays and the mail is sent.

    But when i try a wrong username or email or nothing in the field, the error message only displays “0”.

    Can you help me please to display the corresponding error message instead of “0”.

    Best regards

    • Gael GERARD

      Problem solved!!

      In the php i replaced from line 48 to 55
      if ( $errors->get_error_code() )
      return $errors;

      if ( !$user_data ) {
      $errors->add('invalidcombo', __('ERROR: Invalid username or email.'));
      return $errors;

      with this code :

      if ( $errors->get_error_code() || !$user_data ) {
      $errors->add('invalidcombo', __('ERROR: Invalid username or email.'));
      $errors->get_error_message( $errors->get_error_code() );

      • Don’t forget to add

        // return proper result

        in your AJAX file