I need to add an attribute to the body tag from a controller. Adding a body tag with hook_preprocess_HOOK() is not a problem.

 * Implements hook_preprocess_HOOK().
function MY_MODULE_preprocess_html(&$variables) {
  if (\Drupal::routeMatch()->getRouteName() == 'my.route') {
    $variables['attributes']['class'][] = 'my-class';

However, I only want to add the attribute when the node object, which is already in the controller, meets a second condition which is:

if ((\Drupal::routeMatch()->getRouteName() == 'my.route') && ($this->moderationInformation->hasPendingRevision($node))) {}

I don't have $variables in the controller so how can this be done?

  • You didn't provide any details about the custom route, but since it points to a controller displaying a node object it should contain the node as a route parameter, see drupal.stackexchange.com/questions/220301/…
    – 4k4
    Jul 18 '18 at 12:14
  • It turns out we didn't have to add a body tag, which allowed for a this simple addition to the build: $build += [ '#type' => 'container', '#attributes' => ['class' => 'my-class'], ]; Leaving the question open for now since I would still like to know how to add a body tag from the controller. Remember that we're on the controller here. A hook won't help in this case.
    – esod
    Jul 18 '18 at 18:02
  • To further clarify, we're in the controller, which is on a route, obviously. A preprocess hook won't help because although the route has the node object, we're not on a node.
    – esod
    Jul 18 '18 at 18:11

Rendered output from a controller or other page elements like blocks or menus don't have direct access to the variables of a page/html preprocess hook. You can however attach metadata to the render array which then bubbles up to the page level when rendered, for example html_head or css libraries. In your case one possible way would be to attach a placeholder to the render array of the controller, which then replaces a placeholder class in the body tag. But I still would prefer to get the node via the route parameter, see the linked topic in the first comment.

A code example how to replace a body tag class from a controller. First add a placeholder class in the preprocess hook:

 * Implements hook_preprocess_HOOK() for html.html.twig.
function mymodule_preprocess_html(&$variables) {
  $variables['attributes']['class'][] = 'body-placeholder-class';

And then attach a placeholder to the build array to replace this class from the controller:

$build['#attached'] = [
  'placeholders' => [
    'body-placeholder-class' => [
      '#markup' => 'class-replaced-by-controller',
return $build;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.