Preprocessing and modifying attributes in the .theme file
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
Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.