2

I'm trying to modify Craft 3's example 'Change password' form to work with a logged in Commerce 2 user, and have copied that code to templates/setpassword.twig.

Two problems...

(1) The {{ code }} and {{ id }} variables throw Don't exist errors.

(2) If I comment those variables out, I get a Page not found/"Unable to resolve the request: users/setPassword" error when submitting the form.

Clearly I'm doing this totally wrong 🙃... can anyone set me straight?

<form method="post" accept-charset="UTF-8">
{{ csrfInput() }}
<input type="hidden" name="action" value="users/set-password">
<input type="hidden" name="code" value="{{ code }}">
<input type="hidden" name="id" value="{{ id }}">

<h3><label for="newPassword">New Password</label></h3>
<input id="newPassword" type="password" name="newPassword">
{% if errors is defined %}
    <ul class="errors">
        {% for error in errors %}
            <li>{{ error }}</li>
        {% endfor %}
    </ul>
{% endif %}

<input type="submit" value="Submit">

2
  • Is this for when a user forgets their password, or do you want a form that allows them to change their password at their leisure? Commented Oct 30, 2018 at 12:09
  • One that lets them change it at leisure : ) Commented Oct 30, 2018 at 13:46

2 Answers 2

4

The code you are currently using is for the Set Password form that is used when a user forgets their password and you send them a Password reset email as documented at https://docs.craftcms.com/v3/dev/examples/set-password-form.html.

Here is what I'm using to allow users to change their passwords on demand. It is based on the User Profile Form documented at https://docs.craftcms.com/v3/dev/examples/user-profile-form.html

<form method="post" accept-charset="UTF-8">
    {{ csrfInput() }}
    <input type="hidden" name="action" value="users/save-user">
    {# Change to suit your needs #}
    {{ redirectInput('users/'~currentUser.username) }}
    {# Get logged-in user's ID #}
    <input type="hidden" name="userId" value="{{ currentUser.id }}">

    {% macro errorList(errors) %}
        {% if errors %}
            <ul class="errors">
                {% for error in errors %}
                    <li>{{ error }}</li>
                {% endfor %}
            </ul>
        {% endif %}
    {% endmacro %}

    {% from _self import errorList %}

    {# Enter current password #}
    <h3><label for="password">Current Password</label></h3>
    <input id="password" type="password" name="password">

    {% if account is defined %}
        {{ errorList(user.getErrors('password')) }}
    {% endif %}

    {# Enter new password #}
    <h3><label for="newPassword">New Password</label></h3>
    <input id="newPassword" type="password" name="newPassword">

    {% if account is defined %}
        {{ errorList(user.getErrors('newPassword')) }}
    {% endif %}

    <input type="submit" value="Submit">
</form>

UPDATE: updated form to include error handling.

0
-1

I raised a PR for this last week but it was closed. Apparently you're not supposed to load those templates from the front end as those variables are not auto-populated by craft. (This code fixes the problem)

1
  • Note: use that on your own risk. I wouldn't recommend doing so Commented Oct 30, 2018 at 15:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.