For example, Imagine that I designed two main-menu with different style and template one for the header region (top bar, primary menu section) and another for the footer region as a "footer map" on my site as it's common in the most sites.

Since Drupal 8 it's 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").

In Drupal 7 it was possible to specify separate block templates per region, such as block--header.tpl.php and block--footer.php to output different HTML for blocks placed in the header and footer regions. It was also possible to adjust variables based on the region in hook_preprocess_block(). Both of these features have been removed.

I decide to use below code, by using the below code I can add block region and id to the block template name suggestion:

function MYTHEME_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'];

If I have considered tree or even more footer region in my theme then my theme users should have this freedom to change the order of displaying this designed footer menu independent of which sub-footer region that's inserted in;
It is more useful if we design in LTR languages (Like English) and RTL languages(Like Persian)Simultaneously.
But what's that become outputted from above code is something like this:

I think it's a good idea to design the different menu with different semantic name template separately. It's quite obvious if I need multi instances of a block then Its must probably be in different region, therefore, this difference in positioning make a good and sufficient semantic name convention to assign name to templates and get rid of complication.

for this reason, I want to remove the numbers from the end of block identifier because I think this is very dedicated and I want to achieve something like this:


Something else that I want to pay attention to it is if I choose another footer names for example: footer_menue instead of footer_1 then this hasn't necessary dynamics in theme layer due to the above reasons.

Anyway, the name convention that I like and follow out is:
What's this?(Most common part) it's block or page or....
Where should be placed? header, footer....
What is his name or usage? main-menu, Search Block,...
Like:Block+Region Name without Number+ Block(id) name without number

  • You could use preg_match or explode on those two values to get only the first portion.
    – user21641
    Commented Jul 9, 2017 at 20:16
  • 2
    $suggestions[] = 'block__' . explode('-', $block->getRegion())[0] .. very very simple example. You have to check the content first of course.
    – user21641
    Commented Jul 9, 2017 at 20:23
  • 2
    Or preg_replace('[^a-zA-Z]', '', $block->getRegion())
    – user21641
    Commented Jul 9, 2017 at 20:24
  • If you ever create another menu based on the Main Navigation, now you will have templates that collide.
    – Kevin
    Commented Jul 9, 2017 at 20:29
  • Same for regions named footer_1, footer_2, etc
    – Clive
    Commented Jul 9, 2017 at 20:30

1 Answer 1


If you want to have more meaningful template suggestions, why don't you use better region names and block ids?

Region names are up to your theme, so instead of footer_1, use footer_something, and block configuration names are also up to how you configure/name your blocks.

You could use PHP to filter those things out, that's nothing really drupal specific, but that's likely increasingly complicated as you will have blocks and regions without those number suffixes, so you need to be caruful in not cutting those off.

Also, you could use suggestions based on the block plugin ID, not configuration ID, then placing the same menu multiple times will give you the same template suggestion.

Edit: If you really want to get rid of those kind of suffixes, then you could for example use trim:

rtrim('footer_1', '123_');

You can put whatever characters in there that you want, and it will remove them all from the right side of the string (there is also ltrim for left and just trim for both sides). Note that this will also remove a _ at the end if you have that.

  • Thank you so much, I appreciate you a lot for your beneficial answer, But I think I not clearly explained my mean, That's why I updated my post, Please read my new post. I'm eager to know your new opinion about it. Thanks. Commented Jul 10, 2017 at 3:32
  • Updated the answer.
    – Berdir
    Commented Jul 10, 2017 at 6:26

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.