DEV Community

Cover image for Drupal 8/9: Adding Alternating Class Names to Views Rows with Twig
TrainingCloud.io
TrainingCloud.io

Posted on • Originally published at trainingcloud.io

Drupal 8/9: Adding Alternating Class Names to Views Rows with Twig

Problem

You've created a view, and would like each row of the view result to have an alternating class name, like even and odd. This is also referred to as 'zebra styles'.

Solution

Approach

Override the appropriate twig template file and add a bit of twig logic to make the alternating class names happen.

Spoiler alert: it will only take a single line of custom code.

Steps

  • determine the appropriate template file to copy from /core/modules/views/templates
  • copy the file over to /themes/custom/YOUR_THEME/templates/views
  • rename the file, taking into account Drupal's Twig template naming conventions
  • add your custom logic to the file
  • clear your caches

Implementation

In this example:

  • our view is an unformatted list of articles
  • our view's identifier (machine name) is articles

Step 1: copy the right template file into your theme

Since the view's format is set to unformatted list, copy /core/modules/views/templates/views-view-unformatted.html.twig to /themes/custom/YOUR_THEME/templates/views/.

Drupal will always check your theme folder first for template files to use. If it doesn't find an appropriate template file, it will fall back on the default ones.

Step 2: rename your template file (if appropriate)

If you don't rename your copied template file at this point, any changes you make will apply to all of your site's views that use the unformatted_list format setting.

In you want this template to only apply to your articles view, rename the copied template to:

/themes/custom/YOUR_THEME/templates/views/templates/views-view-unformatted--articles.html.twig

→ See also: Drupal 8/9 Twig template naming conventions

Step 3: add your logic

Here's the default, unmodified Twig template file (comments removed):

→ /core/modules/views/templates/views-view-unformatted.html.twig

{% if title %}
  <h3>{{ title }}</h3>
{% endif %}
{% for row in rows %}
  {%
    set row_classes = [
      default_row_class ? 'views-row',
    ]
  %}
  <div{{ row.attributes.addClass(row_classes) }}>
    {{- row.content -}}
  </div>
{% endfor %}
Enter fullscreen mode Exit fullscreen mode

In your copied tempate file, under default_row_class ? 'views-row', add the following single line of code:

cycle(['even', 'odd'], loop.index0)
Enter fullscreen mode Exit fullscreen mode

So the complete code becomes:

→ /themes/custom/YOUR_THEME/templates/views/templates/views-view-unformatted--articles.html.twig

{% if title %}
  <h3>{{ title }}</h3>
{% endif %}
{% for row in rows %}
  {%
    set row_classes = [
      default_row_class ? 'views-row',
      cycle(['even', 'odd'], loop.index0),
    ]
  %}
  <div{{ row.attributes.addClass(row_classes) }}>
    {{- row.content -}}
  </div>
{% endfor %}
Enter fullscreen mode Exit fullscreen mode

Explanation

  • cycle() is a core twig function that cycles through a given array of values.
  • loop.index0 indicates the position (index) of the iterator during the looping, starting at 0.

→ More info on twig functions: https://twig.sensiolabs.org/doc/2.x/functions/index.html.

Since this template file will be used each time a row of the articles view is rendered, either 'even' or 'odd' will be added to row_classes, which holds the list of classes to be used in the <div> that wraps around the row's { row.content }.


Summary

Override the default views-view-unformatted.html.twig template and add your logic:

  • Copy /core/modules/views/templates/views-view-unformatted.html.twig into your theme.
  • Rename the template file so it applies only to your target view.
  • Add a line of code that cycles between two given class names.
  • Clear your caches.

Further resources


If you liked this article, you'll love our courses on Drupal 8/9 Site Building, Module Development, and Theme Development.

TrainingCloud: Drupal and PHP training for (aspiring) developers

Top comments (0)