I'm putting this here for my own future reference, because I know it's something I'll google in a year and be happy to find!

First, implement hook_preprocess_field().

However, it's best to target the specific field that you want to add the class to, so that the function is run for every field on every page. You can do this by enabling theme debugging, and looking at the theme suggestions in the code. Find the field, choose the template suggestion, drop the .html.twig, and convert hyphens to underscores.

In my case, I wanted to add a class field_account_bio() on the user profile. The template suggestion was: field--user--field-account-bio.html.twig. So I named my function hook_preprocess_field__user__field_account_bio():

function hook_preprocess_field__user__field_account_bio(&$vars)
{
  foreach(array_keys($vars['items']) as $delta)
  {
    $vars['items'][$delta]['attributes']->setAttribute('class', 'some_class');
  }
}

Note that I was actually working with another attribute, not class, so you may need to first retrieve the existing classes and append them, rather than just setting it as I have. Once someone tests this, please post your findings here and I'll alter the code if/as necessary.

Comments

CatsFromStonehenge’s picture

Hi Jaypan

Was this so you could style the user profiles, or did you have some other use? I'm trying to work out some use-cases for this one.

Looks very interesting.

Thanks for sharing :-)

Jaypan’s picture

I was setting up Structured data (aka RDF) on a user profile, for SEO purposes. Specifically, I needed to add property="schema:description" to the field.

Coyote6GraphX’s picture

Be careful on the difference between multiple and single values on field.  Took me a bit to figure out why it was failing.  If it is a single value field, it will not print the wrapper around each field item, therefore causing the attribute not to print.   I added a check to add them to the main field container if a single value.

function HOOK_preprocess_field (&$vars, $hook) {
  if (!$vars['multiple']) {
    $vars['attributes']['class'][] = 'some_class';
    $vars['attributes']['data-attr'] = 'some_attr';
  }
  foreach ($vars['items'] as $delta => &$item) {      
    $item['attributes']->setAttribute('class', 'some_class');
    $item['attributes']->setAttribute('data-attr', 'some_attr');
  } 
}

This way it catches the attributes whether the fields limit value is set to 1 or more.