0

I'm trying to iterate through a user reference field using twig. I'm able to get the username, but not any of the custom fields that I made for users such as "First Name" and "Last Name".

{% for item in items %}
  {{ kint(item.content['#options']) }}
  {{ item.content['#title'] }}
{% endfor %}

I'm trying to get the email address as well, but I can't figure out how to get these values.

enter image description here

I thought it would be something like:

{{ item.content['#options'].entity.mail }}

When I do that, the entire site crashes and I get errors. Am I doing something wrong?

2
  • 1
    You shouldn’t be trying to pick apart the items like that in a field template, just let them render. You’ve got a reference field, so setup the view mode it’s pointing at to render it, start there.
    – Kevin
    Dec 8, 2017 at 23:48
  • OK I see what you mean. I had copied that from the block template that I was working on. So now I'm just using {{ content }}. Still can't access the custom fields though. Dec 9, 2017 at 0:07

1 Answer 1

2

You should never try to display field values by going that deep into structured field properties data within your Twig templates.

Consider using according field displays, or hook_preprocess_HOOK() to preprocess your template variables, e.g. by providing a simple array of preprocessed item data the template can iterate over (an abstract example to put into your mytheme.theme file; where you have to replace mytheme with the name of your theme and themehook with the template's theme registry hook - usually the template name with underscores instead of dashes):

/**
 * Implements hook_preprocess_HOOK().
 */
function mytheme_preprocess_themehook(&$variables) {
  // This will be the new list variable to attach to the
  // template.
  $users_list = [];

  // Get the entity object from existing theme variables.
  // This example assumes you have a node entity in
  // your variables array already.
  $entity = $variables['#node'];

  // Load all referenced users from a field named
  // 'field_users_entityreference'.
  $users = $entity->get('field_users_entityreference')->referencedEntities();

  // Iterate through all users found.
  if (!empty($users)) {
    foreach($users as $user) {
      $item = [
        // Add whichever properties you'd like
        // to show within your template.
        'email' => $user->getEmail(),
      ];
      $users_list[] = $item;
    }
  }

  // Attach the new variable to the template.
  $variables['users_list'] = $users_list;
}

In your Twig template you can now access the users list by accessing the new users_list variable:

{% if users_list %}
  {% for item in users_list %}
    {{ item.email }}
  {% endfor %}
{% endif %}

EDIT:

According to the template name you provided, you are trying to alter how the entity reference field itself is displayed. Generally you have the following choices:

(1) Using field display: Add an according display to the user entity and change the field display to rendered Entity using this display. You can do so by

  • Go to "Admin / Structure / Display modes / View modes".
  • Find the User entity (should be somewhere at the bottom) and add a new user view mode.
  • Then go to "Admin / Configuration / People / Account settings / Manage display".
  • Choose the newly created view mode and add all fields you want to show.
  • Within "Admin / Structure", head to the entity using the reference field and find the "Manage display" tab.
  • At the field in question change the Format to rendered entity and choose your newly created display mode by clicking the cogwheel at the very right of the row.

This approach usually fits your needs if you don't want to digg too deep into programming. Unfortunately you'd like to show the email address. This field is usually not available in user displays (privacy reasons; re-consider if you really want to show it). If you like to add that field to a regular user view, you'd have to additionally implement hook_ENTITY_TYPE_view().

(2) Alter the additional template variables within a preprocessing hook:

  • Within "Admin / Structure", head to the entity using the reference field and find the "Manage display" tab.
  • At the field in question change the Format to Entity ID.
  • Implement a preprocessing hook as described above.
  • Fetch the item IDs from the existing variables and load the user entities.
  • Attach your information to the variables and use it within your template:

    $users = \Drupal\user\Entity\User::loadMultiple($variables['items']);

13
  • Thanks for this. I'm still trying to figure out how to make these theme hooks and how twig is used with that. Odd that twig is supposed to be easier for people, but you have to do a lot more hooks to access data it seems like. So the template name is: field--block-content--field-users.html.twig You're saying the template theme hook would be field__block_content_field_users? mytheme_preprocess_field__block_content_field_users ? Dec 9, 2017 at 0:36
  • Should work, if you use two underscores between block_content and field_users. Don't forget to flush your caches after you added this hook to your theme. Dec 9, 2017 at 0:44
  • And yes, twig makes the work for themers easier, given the theme/modules provide the rightful data, which you can assure through preprocessing. ;) Dec 9, 2017 at 0:45
  • I can't seem to make this work. I'm using themename_preprocess_preprocess_field__block_content__field_users and using the name of my theme. I didn't realize that you had to do a theme hook for every single field you want to theme. Seems like the .theme file would be enormous after you theme everything. I'll end up having to theme something like 50 fields in this project. Dec 9, 2017 at 1:14
  • You don't. You can either add the first mentioned preprocessing to the top level template (as e.g. the block view template, or the node view template), or you do it for some specific fields only as I added within my last edit to the answer. Dec 9, 2017 at 1:33

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.