Reader small image

You're reading from  Drupal 10 Masterclass

Product typeBook
Published inDec 2023
PublisherPackt
ISBN-139781837633104
Edition1st Edition
Tools
Concepts
Right arrow
Author (1)
Adam Bergstein
Adam Bergstein
author image
Adam Bergstein

Adam Bergstein is a product engineering leader and an architect. He has been a long-time Drupal community member, a routine speaker at Drupal community events around the globe, and provided keynotes for several events. He has maintained and contributed to many Drupal projects, including Password Policy, Taxonomy Menu, and more. Adam is the lead of Simplytest, a free service, and a project that offers Drupal community members testing sandboxes. He has also worked for both agencies building Drupal applications and Drupal service providers building Drupal-related products. He has led the Drupal Community Governance Task Force and is serving a term as a community board member of the Drupal Association.
Read more about Adam Bergstein

Right arrow

Theme Development

In this chapter, you’ll learn about theming Drupal. Drupal theming is different from many other content management systems (including WordPress) because the functionality (which is typically handled at the module layer) is separated from the theme layer. Nevertheless, Drupal gives the developer nearly full control over the markup, styles, and JavaScript (JS) interactions of the frontend, which enables the developer to display data however they wish.

In this chapter, we’re going to cover the following main topics:

  • Set up
  • Working with Libraries (JS and CSS)
  • Working with Templates
  • Preprocessing data and PHP
  • Working with CSS
  • Working with JavaScript
  • Single directory components
  • Drupal Accessibility tips
  • Contributed modules that help with theming

Technical requirements

Given this is an advanced chapter, some specific technical knowledge is assumed. Themes in Drupal leverage CSS, JavaScript, and HTML. This book does not cover these topics in depth given they are not specific to Drupal.

As stated earlier, functionality built in Drupal is typically put together using entities, views, display modes etc. All of these exist outside of the theme layer. The theme layer exists to change markup around existing functionality, and add the ability to style and add interactivity to it.

As of the time of this writing, Drupal’s paid theme ecosystem is very small (compared to other CMSs such as WordPress) because of several reasons:

It’s hard to style functionality that the theme author doesn’t know will exist

Most Drupal sites tend to be on the larger side, and require custom bespoke designs

Setting up for theme development

Drupal gives you several tools to help you develop your theme, but you’ll need to enable them. Theme development capabilities should only be enabled on development systems, not production.

Disabling CSS and JS aggregation

Drupal will bundle CSS and JS files together. While this is great for performance, it makes development difficult. To disable this, navigate to Admin | Configuration | Development | Performance. You’ll end up at admin/config/development/performance. The following figure shows the options for Aggregate CSS files and Aggregate JavaScript files:

Figure 19.1 – Aggregation settings

Figure 19.1 – Aggregation settings

Note you can also disable these via code, by adding the following to your sites/default/settings.php file:

$config['system.performance']['css']['preprocess'] = FALSE;
$config['system.performance']['js']['preprocess'] = FALSE;

That ensures...

Creating a new theme from a base theme (subtheming)

Drupal supports a concept of subtheming, where you can declare your theme a subtheme, and it will inherit everything from the parent theme. This is useful when you want to implement a framework such as Bootstrap or U.S. Web Design System (USWDS).

Popular base themes

The community offers several base themes that can be found on Drupal.org:

Working with Libraries API (and where to put CSS/JS)

The method by which themes and modules attach CSS and JS to a page is through Libraries API. This is extendable, very flexible, and easy to use.

To create a library, first create a themename.libraries.yml file in the root of your theme. Within this file, you can create a library using YML syntax:

card:
  css:
    component:
      css/components/card.css: {}
  js:
    js/card.js: {}

This library can then be loaded through one of many following methods.

Loading the library globally through your theme’s *.info.yml file

You can tell your theme to always load the library by specifying it in the theme’s *.info.yml file:

libraries:
  - mytheme/card

Attaching the library through a Twig template

This will ensure the library is loaded once whenever the Twig template is in use:

{{ attach_library('mytheme...

Working with templates

Templates help provide variables inside of HTML markup to define the rendering of content in Drupal. The following sections outline how to work with templates.

How to find and create templates

One of the first things you’ll need to do is figure out what template to use and create. You can find current templates that enable Twig Debug (which we talked about earlier) at /admin/config/development/settings.

Doing so will tell Drupal to output HTML comments in the markup that indicate what templates are in use, and what templates are available. Note that your theme’s templates (except Single Directory Components) will reside in the theme’s /templates directory.

Figure 19.4 – Template suggestions in rendered HTML comments

Figure 19.4 – Template suggestions in rendered HTML comments

In the preceding example, you can see under FILE NAME SUGGESTIONS: that six items are listed, with X next to the last (node.html.twig). This means that node.html.twig is in use, and...

Preprocessing data and PHP

Frequently, you want to modify or create variables before they reach the template. You can do this within the theme’s themename.theme file. This is a pure PHP file in which you can use hooks to do so.

To find the hook that you’re looking for, enable theme debugging at /admin/config/development/settings. When you inspect the markup for the template, you’ll see THEME HOOK.

Figure 19.6 – An example of a theme hook in the rendered markup

Figure 19.6 – An example of a theme hook in the rendered markup

In the preceding screenshot, the hook is node.

To make use of this, you can create a function called themename_preprocess_node within your theme’s themename.theme file. It takes an array as a parameter, $variables. This array contains all the variables that are available in the template:

/**
 * Implements hook_preprocess_HOOK() for node.html.twig.
 */
function themename_preprocess_node(&$variables) {
  // Create an additional variable for...

Working with CSS

Drupal expects specific conventions when it comes to implementing CSS. Typically, CSS files go into a themename/css directory, but that’s not necessary. Drupal themes are free to use Sass, PostCSS, or other build processes as they see fit.

For the theme to load a CSS file, the file must be referenced from a library. Then, the library must be called from either the themename.info.yml file, attached in preprocess, attached within the template through the attach_library function, or loaded by a module.

Drupal core has a set of CSS standards that requires the use of block element modifier (BEM) architecture. Generally, this is best practice within all themes, but it isn’t required. In addition, many popular utility-based CSS frameworks such as Tailwind or Bootstrap negate the need for BEM.

The basics of BEM is that you give your component (aka a “block”) a name. In this case, the name will be a card. Then, any elements inside of that...

Working with JS

Much like CSS, for JS to be loaded, the script needs to be referenced by a library, and then the library needs to be loaded by the theme. The JS can be placed in any directory but is typically placed in the themename/js directory.

Drupal behaviors

Drupal behaviors is the term for the JavaScript API that allows JS to process elements that are injected via AJAX.

It usually runs multiple times when a page is loaded. It’ll run first and pass in the document as context. The subsequent times it loads it will then pass in the AJAX element as context:

((Drupal) => {
  Drupal.behaviors.myBehavior = {
    attach(context) {
      context.querySelector('.my-element')?.addClass('is-processed');
    },
  };
})(Drupal);

In the preceding example, we create a behavior called myBehavior. We add this to the Drupal.behaviors array that Drupal runs whenever...

Single Directory Components

Single Directory Components (SDC) were added to Drupal 10.1 as an experimental module, and they are expected to be stable in Drupal core around 10.3.0. They are Drupal’s implementation of component-based architecture.

While experimental, the SDC module needs to be explicitly enabled. After SDC stabilizes, it will just be part of the theme system, with no separate module.

To use SDC, you’ll need to create a themename/components directory, with a minimum of componentName.component.yml and componentName.twig files. You can add componentName.css and componentName.js as well, and they’ll be included when the component is loaded. Once the component is created, it can be included in another template using Twig’s built-in include() function or embed tag.

The benefit of using SDC is that relevant code is grouped, and libraries are automatically generated. In addition, it enables quick reusable components that can be moved from...

Drupal accessibility tips

While Drupal core’s accessibility is top-notch, custom themes rely on a frontend developer to ensure proper web accessibility. While most accessibility techniques are out of scope for this book, Drupal does contain several techniques to help save you time.

The visually hidden CSS class

The visually-hidden CSS class will hide an element visually, but it will still be apparent to the accessibility tree so that screen readers and other assistive technologies can access it.

Drupal announce JS API

The Drupal.announce() JS function is a way to easily add text to an ARIA live region so that screen reader users will be aware of the text that is passed in:

Drupal.announce('The application has been updated.');

Using buttons as menu items

While more content than theming, be aware that menu items can take <button>, which will generate a <button> HTML element. This is useful to show/toggle child menu items. Note that you...

Contributed modules that help with theming

Many people have created contributed modules to help theme Drupal. Some of the most popular ones are as follows:

There are many more modules than these. If you run into issues, search and you’ll likely find what you’re looking for.

Summary

Drupal provides theming as a means of controlling the visual display of a Drupal application. Themes exist for both frontend and administrative visuals and adding them is a non-trivial development task. This chapter covered the major aspects of a theme in CSS, JS, Twig templates, and the expected Drupal directories and configuration. Best practices were covered for development, debugging, and so on. Emerging concepts such as single-file directories and community-related contributions also can help address specific use cases.

The next chapter covers Drupal’s features tied to web service APIs that enable decoupled and headless application use cases.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Drupal 10 Masterclass
Published in: Dec 2023Publisher: PacktISBN-13: 9781837633104
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Adam Bergstein

Adam Bergstein is a product engineering leader and an architect. He has been a long-time Drupal community member, a routine speaker at Drupal community events around the globe, and provided keynotes for several events. He has maintained and contributed to many Drupal projects, including Password Policy, Taxonomy Menu, and more. Adam is the lead of Simplytest, a free service, and a project that offers Drupal community members testing sandboxes. He has also worked for both agencies building Drupal applications and Drupal service providers building Drupal-related products. He has led the Drupal Community Governance Task Force and is serving a term as a community board member of the Drupal Association.
Read more about Adam Bergstein