How to theme Drupal 8 views by overriding default templates

In this post, you will learn how to theme Drupal 8 views by overriding default views templates and use our own markup to build an accordion (based on bootstrap 3 accordion). We will begin by identifying a custom theme for our newly installed Drupal 8 site and add bootstrap 3 css and javascript files.

This is all we need to create a new theme.

    ├── demotheme.info.yml
    ├── demotheme.libraries.yml
    ├── css
    │   ├── bootstrap-theme.min.css
    │   └── bootstrap.min.css
    └── js
        └── bootstrap.min.js

Then we will create a new view from "admin/structure/views/add" to show latest added articles.

  • View basic information: We will name our view "Articles Accordion" (machine name: "articles_accordion").
  • View settings: Choose (Show: Content), (of type: Article) and (sorted by: Newly first).
  • Page settings: Check "Create a page" and set "Page title" and "Path" to your liking. Under "Page display settings" choose (Display format: Unformatted list), (of: fields).
  • Click "Save and edit"

Here is a screenshot for our view initial settings:


After saving the view we will click on "Content: Title" and uncheck "Link to the Content", then add the "Body" field.

Here is a screenshot for the view final settings:


Understanding Views Templates

Views default templates are located under "/core/modules/views/templates/" folder.

Each view uses minimum of two templates:

  • The first template is "views-view.html.twig". This template is used for all views and contains the layout for the view. (view content, header, footer, exposed form and attachments)
  • The second template is the style template. The default used template will vary based on the applied view style (grid, table, html list or unformatted).
    • Grid: views-view-grid.html.twig
    • Table: views-view-table.html.twig
    • HTML List: views-view-list.html.twig
    • Unformatted: views-view-unformatted.html.twig
  • The third template is "views-view-fields.html.twig". This template is used only if the view row style is set to "Fields". This template is responsible for looping through available fields and print fields wrappers, labels and markup.
  • The fourth template is "views-view-field.html.twig". This template is used only if the view row style is set to "Fields". This is the last template and is responsible for printing each field markup.

Naming Views Templates

Each type of the view templates above can be overridden with a variety of names. The template name is a concatenation of (base template name, view machine name, view display type and view display id - separated by 2 hyphens "--").

The following are the possible template names sorted by precedence:

  • [base template name]--[view machine name]--[view display id].html.twig
  • [base template name]--[view machine name]--[view display type].html.twig
  • [base template name]--[view display type].html.twig
  • [base template name]--[view machine name].html.twig
  • [base template name].html.twig

For example; If we want to override "views-view.html.twig" template for our view, the following template names are valid:

  • [base template name]--[view machine name].html.twig
  • views-view--articles-accordion--page.html.twig
  • views-view--page.html.twig
  • views-view--articles-accordion.html.twig
  • views-view.html.twig

Building Our Bootstrap Accordion

To build our version of bootstrap accordion, we will need to override "views-view-unformatted.html.twig" (because this is the style in use) and "views-view-fields.html.twig".

The easiest way to get started is to copy the templates from /core/modules/views/templates folder into our theme folder and then rename "views-view-unformatted.html.twig" to "views-view-unformatted--articles-accordion--page-1.html.twig" and "views-view-fields.html.twig" to "views-view-fields--articles-accordion--page.html.twig"

{% for row in rows %} {% set row_classes = [ default_row_class ? 'views-row', 'panel', 'panel-default', ] %}
{{ row.content }}
{% endfor %}

{{ fields.body.content }}

This is how how our accordion looks like.


Mobile Theming

Sign up for our weekly newsletter


  • by Kwad (not verified)
  • Thu, 01/21/2016 - 07:28

What do you use as base theme?
Could you give your content in demotheme.info.yml and demotheme.libraries.yml?
Thank you for your great article!

  • by muhammad.reda
  • Thu, 01/21/2016 - 20:57

No, I am not using a base theme.
Here is a gist for theme.info and theme.libraries files.

  • by Kwad (not verified)
  • Fri, 01/22/2016 - 06:34

I was wondering if stable base theme is not used when we don't write the line in theme.info:

base theme: stable

Do you think it's false by default (not stable)? Because by default it seems we have still to remove some CCS with "stylesheets-remove".
Many thanks

  • by muhammad.reda
  • Wed, 02/03/2016 - 14:36

I am afraid I don't quite understand. However, theming best practices is not the purpose of this tutorial.

  • by martin (not verified)
  • Fri, 01/22/2016 - 05:04

how come, you name it block-1 and not just block, is it something to do with extending ? also, how would you theme a specific field in a view ? i.e adding attributes to the field_image in a view ?

  • by muhammad.reda
  • Wed, 02/03/2016 - 15:43

First, apologies for the late reply.

Any of [base template name]--[view machine name]--block and [base template name]--[view machine name]--block-1 will work for [view machine name] view.
[base template name]--[view machine name]--block will work for any block in [view machine name] view.
[base template name]--[view machine name]--block-1 will work for the block with display id "block_1" in [view machine name] view AND will override [base template name]--[view machine name]--block template.
Hope this makes sense.

To add a template for a view field, you will need to follow this pattern [base template name]--[view machine name]--[display id]--[field name].twig.html, foe example "views-view-unformatted--articles-accordion--page-1--field-image.html.twig"

  • by MrPoo (not verified)
  • Mon, 05/30/2016 - 08:38

I think the correct pattern is [base template name]--[view machine name]--[display id]--[field name].html.twig (you typed wrong above pattern i guess)
and example is "views-view-field--articles-accordion--page-1--field-image.html.twig"

  • by oliver (not verified)
  • Sat, 04/02/2016 - 01:10

Is it possible within a view to give subheadings to the content? I am sorting my view of articles by tag but want the tag to be a title above all articles of that tag

  • by Ralph (not verified)
  • Tue, 06/14/2016 - 08:38

Well done, I appreciate the help and taking the time to post something useful...

  • by James (not verified)
  • Wed, 08/17/2016 - 04:41

Sorry for the noob question, how did you that you can get the data by calling fields.content.title and fields.content.body? Is there a way to check the available fields and the machine to use in twig templates?

  • by James McBryan (not verified)
  • Mon, 11/14/2016 - 14:31

Is there a way to add these template overrides into a module instead of a theme?

Add new comment