Add an attribute to $variables from a Controller 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(&amp;$variables) {
  if (\Drupal::routeMatch()-&gt;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()-&gt;getRouteName() == 'my.route') &amp;&amp; ($this-&gt;moderationInformation-&gt;hasPendingRevision($node))) {}


I don't have $variables in the controller so how can this be done?
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(&amp;$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' =&gt; [
    'body-placeholder-class' =&gt; [
      '#markup' =&gt; 'class-replaced-by-controller',
    ],
  ],
];
return $build;