logo

Extra Block Types (EBT) - New Layout Builder experience❗

Extra Block Types (EBT) - styled, customizable block types: Slideshows, Tabs, Cards, Accordions and many others. Built-in settings for background, DOM Box, javascript plugins. Experience the future of layout building today.

Demo EBT modules Download EBT modules

❗Extra Paragraph Types (EPT) - New Paragraphs experience

Extra Paragraph Types (EPT) - analogical paragraph based set of modules.

Demo EPT modules Download EPT modules

Scroll

Preprocessing and modifying attributes in the .theme file

13/04/2025, by Ivan

As in Drupal 7, you can influence the output of specific HTML using preprocess functions. For example, if you want to add a class to a menu and prefer to do it at the PHP level, you can. This is a good way to alter theme-related markup, but if you're making changes unrelated to the theme, it's better to write a custom module.

(Note: For documentation purposes here, “mytheme” is your theme’s machine name; for example, “bartik” is the machine name for the Bartik theme.)

To work with preprocess functions:

1. Create or edit a file in your theme’s directory called mytheme.theme

2. Create a function like mytheme_preprocess_HOOK, where HOOK refers to the element you want to target*

3. Write your changes and save

4. Rebuild cache so your changes take effect (if you have Drush installed, run drush cr in the command line)

* HOOK names follow the Twig template naming conventions. To create a hook for page.html.twig, write mytheme_preprocess_page. To create a hook for a node – article.html.twig, use mytheme_preprocess_node__article (replacing dashes with underscores). To find hook names, see the section on Finding template files using debugging.

Let’s assume we want to add a my-menu class to all menus on your site. Assuming your theme is called “mytheme”, you’d write the following function:

/**
* Implements hook_preprocess_HOOK() for menu.html.twig.
*/
function mytheme_preprocess_menu(&$variables) {
  // If there is not an existing class array, create an empty array.
  if (!isset($variables['attributes']['class'])) {
    $variables['attributes']['class'] = [];
  }
  // Merge with any classes that may have been set by other hook_preprocess_menu invocations
  $variables['attributes']['class'] = array_merge($variables['attributes']['class'], ['my-menu']);
}

This is very similar to Drupal 7 and helpful if you want to customize a targeted menu.

You can check the $variables object conditionally to determine which menu you’re working with. Items inside $variables become available in Twig after the theme preprocess runs.

Now to extend our example, let’s say we want to add a my-main-menu class specifically to the main menu on your site. This would be the function:

/**
* Implements hook_preprocess_HOOK() for menu.html.twig.
*/
function mytheme_preprocess_menu(&$variables) {
  if ($variables['menu_name'] == 'main') {
    if (!isset($variables['attributes']['class'])) {
      $variables['attributes']['class'] = [];
    }
    $variables['attributes']['class'] = array_merge($variables['attributes']['class'], ['my-main-menu']);
  }
}

Differences from Drupal 7

The template.php file no longer exists. It has been replaced by mytheme.theme. However, it still functions in much the same way, allowing hooks to alter output.

Other Helpful Links