I've been looking at the following resources:


Allow user to change or delete their photo for their profile from the front end

Front end edit: entry doesn’t get saved

Front end registration form, no errors

To try and put together a profile editing page that returns errors once submitted, but can't seem to get it.

user is equal to either the currentUser or craft.users.id(craft.request.getSegment(3)).first()

<form method="post" accept-charset="UTF-8" enctype="multipart/form-data">

{{ getCsrfInput() }}
<input type="hidden" name="action" value="users/saveUser">
<input type="hidden" name="redirect" value="partners/view/{{ user.id }}">
<input type="hidden" name="userId" value="{{ user.id }}">

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

{% from _self import errorList %}

{{ dump(user.getErrors) }}

<div class="row">
    <div class="col-xs-12 col-sm-6">
        <label for="firstName">First Name:</label>
        <input id="firstName" name="firstName" autocomplete="off" type="text" data-parsley-required="true" value="{{ user.firstName }}">
        {{ errorList(user.getErrors('firstName')) }}
    <div class="col-xs-12 col-sm-6">
        <label for="lastName">Last Name:</label>
        <input id="lastName" name="lastName" autocomplete="off" type="text" data-parsley-required="true" value="{{ user.lastName }}">
        {{ errorList(user.getErrors('lastName')) }}

<div class="row">
    <div class="col-xs-12">
        <label for="email">Email:</label>
        <input id="email" name="email" autocomplete="off" type="email" data-parsley-required="true" data-parsley-type="email" value="{{ user.email }}">
        {{ errorList(user.getErrors('email')) }}

<div class="row">
    <div class="col-xs-12">
        <label for="userPhoto">User Photo:</label>
        {% if user.photoUrl %}
            <img src="{{ user.photoUrl }}" id="userPhoto" width="100" height="100" />
            <input type="hidden" name="deleteUserPhoto" id="deleteUserPhotoInput" value="">
        {% else %}
            <img src="{{ currentUserPhotoUrl }}" width="100" height="100"  alt="No User Photo" />
        {% endif %}
            <input id="profilePhoto" type="file" accept="image/*" capture="camera" name="userPhoto" value="{{ (user.photoUrl ? 'Change Photo' : 'Upload') }}">
        {% if user.photoUrl %}
            <a id="btn-delete-user-photo" class="btn btn-solid btn-xs">Delete</a>
        {% endif %}

<div class="row">
    <div class="col-xs-12">
        <label for="userDescription">User Description</label>
        <textarea id="userDescription" name="fields[userDescription]" autocomplete="off" data-parsley-required="true" value="{{ user.userDescription }}"></textarea>

<button type="submit" class="btn btn-solid">Save</button>


Could anyone point out where I'm going wrong, or provide a working example?

Many thanks!


Not sure what validation error you're expecting from the template code.

Both firstName and lastName are non-required fields that will basically accept any input.

photoUrl could return a validation error if, for example, you tried to upload a .txt file to but you're not calling the errorList() macro on that field.

Not sure if userDescription is required or not, but the errorList() macro isn't being called there, either.

Finally, the variable that Craft returns back to the template when there are validation errors is called account.

So you'd want to do something similar to what the User Registration Form example doc does:

 {% if account is defined %}
    {{ errorList(account.getErrors('userDescription')) }}
{% endif %}
|improve this answer|||||
  • Hi Brad, thanks for your reply. When looking at the documentation for the Registration Form, I saw the account variable, but it wasn't clear whether that was a special super-global created during the registration process (because the user doesn't exist yet) or if it was available on the other pages, such as profile, since the Profile Edit example shows no use of it. I've now edited my code, here: pastebin.com/nT5kNqMx This is now working, so it indeed is the use of the account variable - many thanks! – Robert Tolton Feb 15 '17 at 10:23
  • 2
    Worth noting that in Craft 3, the errors returned to the template are no longer called account, but user. Would be good to add that to the C3 docs as well, as I had to go digging through the UsersController.php file to figure out why it wasn't working. – James Smith Nov 28 '18 at 14:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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