Looping Through User Profile Fields

Problem

You want to loop through the fields that you have specified for user profiles (found under Settings ➜ Users ➜ Fields in your admin CP).

Solution

{% set userProfileFields = craft.fields.getLayoutByType('User').getFields() %}

{% for field in userProfileFields %}
    {% set field = field.getField() %}
    {% set value = attribute(currentUser, field.handle) %}

    {{ field.name }}: {{ value }}
{% endfor %}

How it works

  1. We got the field layout associated with user profiles and assigned it to the userProfileFields variable.
  2. We began looping through that field layout. For each field in the layout, we will: — Get the actual field object using the getField() method, and replace the existing field variable with it. — Get the value that the user has specified (if any) for each field. — Output the name of the field and its value.

Discussion

This method can be used for a variety of purposes on your site’s front end, including (but not limited to):

  1. Displaying a user’s profile:
// In config/routes.php:

// Note that the second URI segment is captured; its contents will be available as the
// variable "username" in the destination template.
'users/(?P<username>[\-\.\w]+)' => 'users/_entry',
{# In templates/users/_entry.twig #}

{% set userProfile       = craft.users.username(username).find() %}
{% set userProfileFields = craft.fields.getLayoutByType('User').getFields() %}

{# Bail if we can't find the user in question #}
{% if username is not defined or not userProfile %}
    {% exit 404 %}
{% endif %}

<ul>
    {% for field in userProfileFields %}
        {% set field = field.getField() %}
        {% set value = attribute(currentUser, field.handle) %}

        {% if value %}
            <li>{{ field.name }}: {{ value }}</li>
        {% endif %}
    {% endfor %}
</ul>
  1. Allowing users to search for other users based on profile contents:
{# In templates/search/index.twig #}

{# Disallow users from basing their searches on the contents of these fields: #}
{% set excludeFields = ['birthdate', 'gender'] %}

{% for field in userProfileFields if field.getField().handle not in excludeFields %}
    {% set field = field.getField() %}
    {% set fieldId = 'profile-fields' ~ field.handle %}

    <label for="{{ fieldId }}">{{ field.name }}:</label>
    <input id="{{ fieldId }}" name="{{ fieldId }}" type="text"/>
{% endfor %}