Programmatically get current multi-site instance name 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(&amp;$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(&amp;$variables) {

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

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

}
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(&amp;$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;

}