Drupal 8/9: Adding Alternating Class Names to Views Rows with Twig
Tags: drupal, theming, snippet, twig
Published: 2021-05-20 14:01:22

## 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`


&rarr; See also: [Drupal 8/9 Twig template naming conventions](https://www.drupal.org/docs/theming-drupal/twig-in-drupal/twig-template-naming-conventions#s-views)

#### Step 3: add your logic

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

&rarr; /core/modules/views/templates/views-view-unformatted.html.twig

```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 %}
```

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

```twig
cycle(['even', 'odd'], loop.index0)
```

So the complete code becomes:

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

```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 %}
```

## 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. 

&rarr; More info on twig functions: [https://twig.sensiolabs.org/doc/2.x/functions/index.html](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 }`.


---

<a id="summary"></a>

## 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

* [Drupal 8/9 Twig template naming conventions](https://www.drupal.org/docs/theming-drupal/twig-in-drupal/twig-template-naming-conventions#s-views)
* [https://twig.sensiolabs.org/doc/2.x/functions/index.html](https://twig.sensiolabs.org/doc/2.x/functions/index.html)

---

If you liked this article, you'll love [our courses](https://trainingcloud.io/courses) on Drupal 8/9 Site Building, Module Development, and Theme Development. 

![TrainingCloud: Drupal and PHP training for (aspiring) developers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2wav7v6hn30d0q9vfy3c.png)