Changing the HTML of Views ‘Grouped by’ in Drupal 8. Sort of.

Sarah Carney
4 min readJan 14, 2021

Drupal 8 Views allow you to group Views rows by Taxonomy terms (as an example). This tutorial is about how to control the HTML and styling of those groups and their headings.

No coding needed.

I’m going to use a clean D8 site with the Bartik theme.

I have a content type Pattern with the taxonomy vocabulary Type with three terms: Knitting, Crochet, Tunisian Crochet. My page view uses ‘grouped by’ to sort Patterns by Type.

Screenshot of a view with 9 patterns sorted under three headings.

The HTML for the grouping looks like this:

<div class="view-content">
<h3>Tunisian Crochet</h3>
<div class="views-row">...</div>
<div class="views-row">...</div>
<div class="views-row">...</div>
<h3>Crochet</h3>
<div class="views-row">...</div>
<div class="views-row">...</div>
<div class="views-row">...</div>
<h3>Knitting</h3>
<div class="views-row">...</div>
<div class="views-row">...</div>
<div class="views-row">...</div>
</div>

There are two things I might want to do:

  1. Change the HTML of the group titles. <h3>Tunisian Crochet</h3>
  2. Wrap each group in HTML.

Changing HTML of ‘Grouped By’ headers

This does not work the way I expect. I expect there to be an option here:

Screenshot of the Grouped by options

And there is, sort of. I can unlock this option because the Use rendered output to group rows option is checked. The ‘rendered output’ is what is produced when you edit the field options below.

I would expect that I could use the Style settings to change the HTML, but that doesn’t work. I don’t know why. It has no effect.

Screenshot of a field’s settings, showing Style Settings

What does work, sort of, is Rewrite results. I can wrap my field’s own token in a new HTML tag such as h2. (It won’t strip out the class attribute which is nice, too.)

Screenshot of the Rewrite results section of a field’s settings

It makes this HTML. Our titles are now nicely wrapped in h2 but the h3 is still there. Whyyyyy. So this works, sort of.

<div class="view-content">
<h3></h3>
<h2>Tunisian Crochet</h2>
<div class="views-row">...</div>
<div class="views-row">...</div>
<div class="views-row">...</div>
<h3></h3>
<h2>Crochet</h2>
<div class="views-row">...</div>
<div class="views-row">...</div>
<div class="views-row">...</div>
<h3></h3>
<h2>Knitting</h2>
<div class="views-row">...</div>
<div class="views-row">...</div>
<div class="views-row">...</div>
</div>

Grouping the rows

Again, I’d expect to be able to do this with a setting on the ‘Grouped by’ settings field but that’s not how it works. Here’s what to do. Sort of.

Change the format to ‘HTML list’.

Screenshot of the rows format selection screen

Why this work. ‘Unformatted list’ isn’t actually a list, it’s just divs. But an ‘HTML list’ is either a ul or ol which by nature have list items wrapped in a list element. Now the ‘Grouped by’ settings have options to add classes.

Screenshot of the Grouped by settings showing the three CSS class fields
  • Row class
  • Wrapper class
  • List class

Here is where those classes appear in the HTML

<div class="wrapper-class">
<h3></h3>
<h2>Tunisian Crochet</h2>
<ul class="list-class">
<li class="row-class">...</li>
<li class="row-class">...</li>
<li class="row-class">...</li>
</ul>
</div>
...

This is great. I have much more control over the design when I can apply CSS classes.

You may notice that ‘wrapper class’ defaults to item-list. In Bartik, this CSS class unstyles the ul or ol inside the wrapper, so it’s visually the same as Unformatted list.

Even better, almost always an HTML list element works well semantically for a View which is a list of things.

Yay!

Using two levels of ‘Grouped by’

I added another field to Pattern called Difficulty which can be set to Beginner, Intermediate, and Advanced. I want to group Patterns under each Type by Difficulty. So I set the ‘Grouping field Nr. 2’ to Difficulty.

Screenshot of 9 patterns sorted by type and difficulty

The HTML are now grouped in another layer of div wrappers with view- CSS classes provided by the View. I didn’t expect this, but I like it.

<div class="view-content">
<div class="view-grouping">
<div class="view-grouping-header">
<h2>Tunisian Crochet</h2>
</div>
<div class="view-grouping-content">
<div class="wrapper-class">
<h3>Advanced</h3>
<ul class="list-class">
<li class="row-class">...</li>
</ul>
</div>
<div class="wrapper-class">
<h3>Intermediate</h3>
<ul class="list-class">
<li class="row-class">...</li>
</ul>
</div>
<div class="wrapper-class">
<h3>Beginner</h3>
<ul class="list-class">
<li class="row-class">...</li>
</ul>
</div>
</div>
</div>
...
</div>

Good news: I can still use ‘Replacement pattern’ on the Difficulty field to change the HTML of the ‘Grouped by Nr 2’. Defaulting to h3 in a two-group scenario often makes sense semantically, but you may want to do something else or add a class.

Strange:

  • The extra h3 is gone from the ‘Grouped by Nr 1’.
  • But it still leaves behind another empty h3 for ‘Grouped by Nr 2’.

I hope this helps. Visual results will vary by theme.

--

--