5

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 @@@;
  }

}
1
  • 2
    I might be missing something, but it looks like you'll have to implement your own logic similar to DrupalKernel::findSitePath, which includes sites/sites.php, breaks down the current host into an appropriate string, and checks the $sites array for a matching key. If your requirements can be satisfied by getting the site folder, e.g. "sites/a" for your first group of sites, then you can just call the static DrupalKernel::findSitePath directly with the current request.
    – Clive
    Mar 8, 2018 at 14:12

2 Answers 2

15

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. But this service got deprecated in Drupal 9 and will have been removed from Drupal 10, so back to to DrupalKernel::findSitePath. This works in Drupal 8, 9 and 10:

/**
 * Implements template_preprocess_html().
 */
function MYTHEME_preprocess_html(&$variables) {
  
  // This will get you a string for example: 'sites/default'.
  $site_path = \Drupal\Core\DrupalKernel::findSitePath(\Drupal::request());

  // Explode it to only get the 'default' part in the next step.
  $site_path = explode('/', $site_path);
  $site_name = $site_path[1];

  // Add current site name as CSS class to the body.
  $variables['attributes']['class'][] = 'site-' . \Drupal\Component\Utility\Html::cleanCssIdentifier($site_name);
}
0
0

A quicker alternative is to add a $settings['current_multisite'] with the desired value on each setting.php then use it for checkings:

<?php
# settings.php of "bar" site
$settings['current_multisite'] = 'foo';

# settings.php of "bar" site
$settings['current_multisite'] = 'bar';

Then you can access it anywhere:

<?php
// Fallbacks to "null" if some multisite did not specified "current_multisite" 
$multisite = Settings::get('current_multisite'); 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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