16

Since Drupal 8 it is not possible with template naming conventions to load a specific block template according to the region it is placed in ("Per-region block markup and per-region block templating feature removed"). But I need to have different html for blocks if placed in a certain region. How do I accomplish this?

I've thought about using MYMODULE_theme_suggestions_block_alter but I don't know how to get the current region.

2 Answers 2

22

You can get region if you get Block Entity.

.module or .theme file

use Drupal\block\Entity\Block;

function MODULE_theme_suggestions_block_alter(array &$suggestions, array $variables) {
  if (!empty($variables['elements']['#id'])) {
    $block = Block::load($variables['elements']['#id']);
    $suggestions[] = 'block__' . $block->getRegion() . '__' . $variables['elements']['#id'];
  }
  /* Use this 'else if' only if you are using page_manager module and want to know which region is the block */
  else if (isset($variables['elements']['#configuration']['region'])) {
    $suggestions[] = 'block__page_' . $variables['elements']['#configuration']['region'] . '__' . end(explode(':', $variables['elements']['#plugin_id']));
  }
  return $suggestions;
}

Edit 1: Cover page_manager module case.

4
  • Almost perfect. You need to add an isset() to make sure that the #id is really there. For example, if you use page_manager and place blocks in there, then you won't have an #id.
    – Berdir
    Feb 25, 2016 at 20:22
  • @Berdir thanks ;) . I think that in this case isset() is not required, because if there isn't an #id, then it pass NULL to ::load function, and just return NULL. In the end, $block is NULL and nothing will happen. Tested in my dev env Drupal 8.0.4 - page_manager-1.0-alpha23 (never used this module before).
    – Vagner
    Feb 25, 2016 at 23:40
  • Yes, isset() is required. accessing an array key that doesn't exist results in a PHP notice. Check your logs and you'll see. I would recommend to always develop with error display on verbose, which is the default of the provided example settings.php.
    – Berdir
    Feb 26, 2016 at 0:12
  • You don't need return $suggestions; at the end since that variable is passed by reference.
    – user16537
    Nov 13, 2020 at 1:35
0

This answer was useful. I ended up with something similar. This snippet appends the region to the existing suggestions.

if (!empty($variables['elements']['#id'])) {
  $block = Block::load($variables['elements']['#id']);
  $region = $block->getRegion();
  $temp_suggestions = $suggestions;
  if (!empty($temp_suggestions)) {
    foreach($temp_suggestions as $key => $val) { 
      $suggestions[] = $val . '__' . $region;
    }
  }
}

Your Answer

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

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