Question

Let's say I have the following multi-site setup:

$sites['hello-world-a.com']       = 'a';
$sites['stage.hello-world-a.com'] = 'a';
$sites['dev.hello-world-a.com']   = 'a';
$sites['hello-world-a.localhost'] = 'a';

$sites['hello-world-b.com']       = 'b';
$sites['stage.hello-world-b.com'] = 'b';
$sites['dev.hello-world-b.com']   = 'b';
$sites['hello-world-b.localhost'] = 'b';

Works fine. Both share the same theme and more or less the same features. Now let's say I have a very simple preprocess function that adds a CSS class to the body:

/**
 * Implements template_preprocess_html().
 */
function MYTHEME_preprocess_html(&$variables) {

  $variables['attributes']['class'][] = 'foo';

}

How can I now add the multi-site instance's name as body class dynamically?

  • Without going through all possible domain names and string comparison?
  • Also possibly without working with the human readable site name, which may change?
  • Maybe with cache contexts?
  • Or UUID?

/**
 * Implements template_preprocess_html().
 */
function MYTHEME_preprocess_html(&$variables) {

  $variables['attributes']['class'][] = 'foo';

  // Basically along the following pattern.
  if ( @@@ SITE A @@@ ) {
    $variables['attributes']['class'][] = @@@ SITE A @@@;
  }

}
Was it helpful?

Solution

Thanks to @Clive for telling me about DrupalKernel::findSitePath which takes the current $request to then return the path of the matching multi-site directory.

And thanks to @4k4 for the tip that there's also a service for that:

/**
 * Implements template_preprocess_html().
 */
function MYTHEME_preprocess_html(&$variables) {

  $site_path = \Drupal::service('site.path'); // e.g.: 'sites/default'    
  $site_path = explode('/', $site_path);
  $site_name = $site_path[1];

  $variables['attributes']['class'][] = 'site-' . $site_name;

}
Licensed under: CC-BY-SA with attribution
Not affiliated with drupal.stackexchange
scroll top