Theming Cheat Sheet for Drupal 8, 9, and 10

Theming Cheat Sheet

Get started theming in Drupal with our Hands-On Theming Guide.

Go to guide

What will you learn

  • Find tutorials related to our Cheat Sheet
  • Twig
  • Templates
  • Overriding templates
  • Twig debugging
  • Inspecting variables


Did you get a Theming Cheat Sheet? Our printed Cheat Sheet contains an example Twig template, steps to overriding a template and inspecting variables, and interpreting Twig debug output. This guide contains the text of our Cheat Sheet along with related tutorials for a quick reference. New to Drupal Theming? Start with our Hands-On Theming guide, based on our popular Drupal Theming Workshop. Our Theme Drupal Sites guide contains a more extensive curriculum.

Cheat Sheet

Override a Template and Discover Variables

1. Turn on Twig debugging.

More information

Making Drupal fast by default implies having caching layers and CSS and JavaScript aggregation utilities enabled out-of-the-box. As a theme developer this can be annoying, because you must clear these various caches in order to preview any changes. In addition, inspecting variables with debugging tools often produces PHP errors. We'll make some recommendations for PHP settings on your local environment that can prevent these errors from happening so often.

By the end of this tutorial, you should be able to:

  • Set up your local Drupal site for theme development
  • Prepare your local development environment for working on and debugging themes

2. View source. Which template is being used?

Look for BEGIN OUTPUT from.

3. Copy the file into your theme’s templates directory. Optional: Rename file to change its scope using File Name Suggestions.

Drupal 8, 9, and 10
More information

This tutorial demonstrates how to locate the template file that is currently being used to render an element and override it in your own theme. This is an important skill for anyone who wants to make changes to Drupal's default HTML markup.

In this tutorial we'll:

  • Override the node.html.twig template in our theme
  • Make changes to the markup
  • Create a content-type-specific template override like node--CONTENT_TYPE.html.twig

By the end of this tutorial you should be able to modify the HTML markup used to display a node, or any other element of the page generated using a template file.

Drupal 8, 9, and 10
More information

If you want to make changes to the HTML markup of any element on the page you need to first figure out the theme hook or base name of the template file used to generate it. This information is required to override the template in your custom theme.

There are other situations in which knowing the theme hook name of a template file is useful. Including determining which preprocess function affects a template, and which template theme hook suggestions can be used.

In this tutorial we'll learn:

  • How to figure out the theme hook name for any template

By the end of this tutorial you should be able to use the output from Twig's debugging mode to determine the theme hook name of any template file.

4. Clear the cache (Configuration > Performance > Clear all caches or drush cr)

Drupal 8, 9, and 10
More information

Knowing how to clear Drupal's cache is an important skill for any developer. You'll likely find yourself doing it frequently in order to get Drupal to register the changes you make to your code, or other updates you make via the UI. It is also a good first step to trouble shooting problems with your Drupal site: Clear the cache before you do any other debugging to ensure it's not just a bad cache entry.

5. Inspect variables.

Use {{ dump(_context|keys) }} in template to see which variables are available.

Drupal 8, 9, and 10
More information

Knowing how to inspect the variables available within a template file enables you to discover all of the dynamic content in a Twig file, not just that which is already being used.

In this tutorial, we'll learn how to use {{ dump() }}, kint(), vardumper(), and XDebug to inspect variables in a template file.

Example Twig Debug Output (View Source)

After turning on Twig debug mode, view source on any page of your Drupal site to see the Twig debug output in HTML comments.

<!-- THEME DEBUG -->
<!-- THEME HOOK: 'page'
  * page--node--1.html.twig
  * page--node--%.html.twig
  * page--node.html.twig
  x page.html.twig
<!-- BEGIN OUTPUT from 'themes/icecream/templates/page.html.twig' -->
Drupal 8, 9, and 10
More information

When determining which template file to use to theme an element, Drupal uses the list of theme hook suggestions to look for the best match. This allows for fine-grained control over how things appear based on dynamic state and contextual information in your application. The list of theme hook suggestions varies for each base template, so we need a way to figure out our options.

In this tutorial we'll look at:

  • How to determine the list of valid theme hook suggestions for any template file
  • How theme hook suggestions are added by modules and themes

By the end of this tutorial you should be able to explain how theme hook suggestions are added, and determine the valid suggestions for any template file.

Twig Template Example

Learn about template variables in comment blocks

{# Learn about template variables in comment blocks
  - items: A list of ice cream flavors
    - title: Link title
  - author: Author of content

Discover variables with dump().

{# Discover variables with dump(). #}
  {{ dump(_context|keys) }}

Attach an asset library in a template

{# Attach an asset library in a template. #}
  {{ attach_library('classy/node') }}

Define a variable

{# Define a variable. #}
{% set date = node.created|format_date('long') %}

Add a CSS class

<article{{ attributes.addClass('about') }}>

Make hard-coded text translatable

  {# Translatable text with vars, use trans. #}
  <p class="byline">{% trans %}by {{ author }} on {{ date }}{% endtrans %}</p>

  {# Translatable text without variables, use t. #}
  <h3>{{ 'Ice Cream Flavors'|t }}</h3>

Iterate over a list with a for loop

  {# Iterate over a list with a for loop. #}
  <ul class="ice-cream-list">
  {% for item in items %}
    <li class="ice-cream-list--flavor">{{ item.title }}</li>
  {% endfor %}

Create a link in a template

  {# Links in templates. If you know the route: #}
   <a href="{{ url('contact.site_page') }}">{{ 'Contact'|t }}</a>
  {# If you don't know the route: #}
  {{ link('Contact'|t, 'base:about/contact', { 'class':[] }) }}


Related tutorials

Drupal 8, 9, and 10
More information

Template files are responsible for the HTML markup of every page generated by Drupal. Any file ending with the .html.twig extension is a template file. These files are composed of standard HTML markup as well as tokens used by the Twig template engine to represent dynamic content that will be substituted into the HTML markup when the template is used. As a theme developer, you'll work with this a lot.

In this tutorial we’re going to learn about:

  • What template files are, and how they fit into the big picture of creating a theme
  • How template files are used in order to allow theme developers to modify the HTML markup output by Drupal
  • Naming conventions for, and specificity of, template files
Drupal 8, 9, and 10
More information

Twig is the default template engine for Drupal. If you want to make changes to the markup that Drupal outputs you're going to need to know at least some Twig. In this tutorial, we will outline the role that Twig now plays in Drupal, how Twig impacts the theming experience, and where to find additional resources for learning Twig.

At the end of this lesson, you'll be able to:

  • Describe the role that Twig plays in creating Drupal themes
  • Explain how Twig impacts the theming experience in Drupal
  • Locate additional resources for learning Twig
Drupal 8, 9, and 10
More information

To read a Twig template file, you'll need to recognize Twig's syntax delimiters. Twig has three syntax delimiters: one for printing out variables, another for performing actions or logic, and lastly, one for comments, also used for docblocks.

In this tutorial we'll:

  • Explore each of Twig's 3 syntax delimiters.
  • Show examples of each from Drupal's core template files.

By the end of this tutorial you should be able to recognize each of Twig's syntax delimiters and understand what the engine will do when it encounters them.

Drupal 8, 9, and 10
More information

Twig has a special syntax for accessing array keys and objects, also known in Twig as variable attributes. In this tutorial, we'll cover the period or dot (.) operator to access a variable attribute, as well as subscript or square-bracket syntax, useful for when the key of the array contains special characters, like a dash (-) or pound sign (#). We'll also look at the logic Twig uses to find the matching attribute in an array or object.

Drupal 8, 9, and 10
More information

Many of the variables that you have access to inside of a Twig template file are arrays. For example a list of values for a multi-value field, or a set of error messages generated when validating a form submission. In order to work with arrays in Twig you'll need to understand how for loops work. This is essential information for anyone creating Drupal themes.

In this tutorial we'll cover:

  • Using the for tag to iterate over an array
  • Using the loop variable inside of a for loop for additional context
Drupal 8, 9, and 10
More information

The ability to loop over an array of values in a Twig template and print out each value individually is an important skill for anyone developing themes for Drupal. Common scenarios include: loop over the values of a multiple value field; iterate through a list of links; and display error messages at the top of forms. This tutorial will provide an example of using the Twig for function to iterate over a list, or a subset of a list.

In this tutorial we'll cover how to:

  • Output values from a multi-value field in an unordered list.
  • Add first and last classes to the first and last items in a list by using the Twig loop variable.

By the end of this tutorial you should be able to print out the values of an array as individual list items using a loop in Twig.

Drupal 8, 9, and 10
More information

In Twig, you can modify variables using functions or filters. Twig has a bunch of built-in functions and filters. Drupal extends Twig to provide a few handy Drupal-specific functions and filters as well.

In this tutorial, we'll look at:

  • What are functions and filters?
  • How to use functions and filters in Twig
  • Detailed information about the Drupal-specific functions and filters and their use case
Drupal 8, 9, and 10
More information

In order to ensure that all user interface strings in your application can be translated using Drupal's localization system, any text you add to templates needs to use either the t filter or the {% trans %} tag. Anyone creating themes or editing template files associated with a theme or a module should know how to use these two utilities.

In this tutorial we'll look at:

  • How to use the t filter and {% trans %} tag in a Twig template
  • The differences between the two, and how to determine which one to use
  • How to translate strings assigned to variables in preprocess functions using the PHP t() function
Drupal 8, 9, and 10
More information

Theme developers often need to add or remove classes and other attributes from an HTML tag. Template files handle this with a special Attributes object that contains the attributes and their values, as well as a handful of powerful methods to help manage these attributes.

In this tutorial we’ll cover:

  • Adding/removing classes from elements in a Twig template
  • The attributes object
  • Examples of common tasks using various helper methods on the attributes object
Drupal 8, 9, and 10
More information

Before you can create a path or link to another page on your site, you'll need to know the route (unless there is already a variable available for the URL you need). Finding a route can be a tricky task unless you have the right tools. In this tutorial, we'll show how tools like Webprofiler, Drush, and Grep can be used to get route information for a page, so that you can use functions that need a route as a function parameter.

In this tutorial we'll:

  • Learn how to determine the route or path of an internal page.
Drupal 8, 9, and 10
More information

Once you've defined an asset library you'll need to tell Drupal when you want to add the CSS and JavaScript that it includes to the page. Ideally you'll do so in a way that allows Drupal to only add the corresponding assets on pages where they are needed.

You can attach a library to all pages, a subset of pages, or to elements in a render array. This allows you to have some assets that are global, and others that get loaded on an as-needed basis. To attach a library you'll need to know both its name and prefix, and then use one of the techniques outlined below to let Drupal know when to include it.

In this tutorial, we'll look at attaching asset libraries:

  • Globally, via your file
  • Conditionally, via a preprocess function using the #attached render array property
  • Inside of a Twig template file

By the end of this tutorial you should be able to attach asset libraries in various different ways depending on your use case.

Further your understanding

Drupal 8, 9, and 10
Drupal 7, 8, 9, and 10
“Drupalize.Me has trained thousands of Drupalistas. Their video lessons help to address our constant need for more Drupal talent. Drupal needs training like this to support its growth.”
Dries Buytaert
Drupal Founder and Project Lead
Photo of Dries Buytaert
“They’re easy to understand. They’re thorough. They’re funny. They’re always entertaining, and it makes it easy to learn parts of Drupal and how you can integrate it into your workflow and learn more and have a good time doing it.”
Roger Carr
Drupalize.Me Member
Photo of Roger Carr
“The mission of the Drupal Association is to foster and support the Drupal software project, the community, and its growth. Drupal education, like that provided by Drupalize.Me, is important to this mission.”
Megan Sanicki
Former Exec. Director, Drupal Assoc.
Photo of Megan Sanicki


Am I required to sign a contract?
No. You can purchase a membership and/or cancel any time. Drupalize.Me is a pay-as-you-go service.

Can I preview tutorials before joining?
Yes! Just navigate to our tutorial library. Our free tutorials are labeled with a green "FREE" tag.

Can I watch videos on my mobile device?
Yes! Drupalize.Me is a responsive site and can be accessed in the browser on any mobile device. More FAQs