0

I have a View that outputs several fields per row. I'd like to use a preprocess function to add a class to one of the fields, depending on the value of another field. How do I do that in Drupal 8?

Note, I do not want to add a class to the entire row -- just a specific field in that row. The output would be something like:

<div class="views-row">
  <div class="views-field field-name-a"> ... </div>
  <div class="views-field field-name-b has-custom-class"> ... </div>
</div>
  • 3
    Did you consider rewriting the output of your field value or using an additional "Global: Text" field where you can use the values of all other fields added before that field with Twig (and even Twig control structures as if...then...else)? - I'm on mobile right now, therefore the brevity. Both suggestions don't require for any preprocess functions. They can be applied within the configuration of your View. – Mario Steinitz Feb 23 at 4:10
2

As mentioned in the comment you can add classes to fields through the interface, and you can use field tokens as CSS classes.

Add field-value-based CSS class to a field

  1. Position the field with the value you want to use as the CSS class (the value-class field) above the field where you want the class to appear (the styled field).
  2. Set the value-class field to Exclude from display if you don't want it to appear there.

    If you need it visible in some other place then add that same field again where you need it, while keeping the first one for the token (because you can only use tokens of fields preceding in the Fields list).

  3. Edit the field where you want to apply the CSS class (the styled field) >

    • Uncollapse Style settings >
    • Customize field and label wrapper HTML (or Customize field HTML if you don't need the wrapper) >
    • Create a CSS class and
    • enter the first part of your class (myclass)

      (class names can't start with numbers and some special characters so it's good to control at least the first character to make it independent of the other field's value to prevent trouble down the line).

  4. Uncollapse Rewrite results (don't enable it, you just need to temporarily reveal and uncollapse to copy the token),

    • uncollapse Replacement patterns,
    • copy the value-class field token and
    • paste it in the above CSS class field

      (you end up with something like myclass-[field_name_a]).

  5. Save the View and check your HTML output (in any theme), you will see a class based on your value-class field on the field where you added the class, something like class="views-field views-field-name-b myclass-namebvalue".
  • Thanks. This assumes that the value of field_name_a is what I want to use as a class name, and is sanitized. The reason I was hoping to be able to do this in a preprocess function is to be able to check the value of field_name_a and then apply some other class name. For example, if the value of field_name_a is "Overview Page A" or "Overview Page B", then the class to apply is "type-overview". Is it possible to do this in Drupal 8 somehow? In D7, you could use template_preprocess_views_view_field(). – confusedGFCI Feb 23 at 20:03
  • Yes, you can still do that in D8, check out views-view-fields.html.twig or views-view-field.html.twig, or use twig logic in Global: Text field as suggested in the comment. Lets hope Mario Steinitz adds his answer ;) Twig best practices - preprocess functions and templates – prkos Feb 23 at 20:25
  • 1
    You don't really need me for this. Your answer is pretty good already. Just add the "Global: Custom text" variant. It can use the very same Replacement patterns and allows for text like that: <div class="views-field {% if field_image %} with-image{% endif %}">{{ field_my_other_field }} {{ field_image }}</div> to print the previously hidden fields field_my_other_field and field_image. – Mario Steinitz Feb 25 at 2:54

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.