I want to be able to create a block or place a block into a region and theme it according to the selected view mode from Panels. I have noticed a discrepancy between Custom Block and Entity Block where one form gives you the view mode to show the block in, and the other does not (Custom Block).

I want the template suggestion to be along the lines of block--provider/module--block-bundle--view-mode.html.twig but struggling to find consistency in the variables in hook_theme_suggestions_block_alter() in order to add the suggestion. At the same time, I want to enforce the template that is used no matter if the user created the block inline, or referenced an existing block via Entity Block. What keys or identifiers can I look for to make this work?

enter image description here

  • 1
    This would be easy, if block_content had a template, then you could add the suggestions to the entity template. So you have to add it to the block plugin, but here you have no consistency because how the entity is referenced depends on the plugin class the different methods use.
    – 4uk4
    Commented Dec 13, 2017 at 9:26
  • 1
    So is this basically not possible? That’s kinda limiting when Panels is being used (so you could theme one block X ways per region and/or Y ways per view mode).
    – Kevin
    Commented Dec 13, 2017 at 13:27
  • 1
    It's possible, but not in a consistent way. In your question you use two different methods to place the block, resulting in different block plugins. If you want I can show this in an answer which plugins are involved.
    – 4uk4
    Commented Dec 13, 2017 at 13:43
  • 1
    Sure, go ahead. It might be on the same path I was already on.
    – Kevin
    Commented Dec 13, 2017 at 14:15

2 Answers 2


Normally a content entity has a template, like node.html.twig for node, so for custom blocks there should be block-content.html.twig. To avoid overhead it was decided to remove this template. This means you can't add template suggestions to the entity template, instead you have to add them to the block template. In this case you get the variables from the plugin when adding suggestions and you don't find the view mode or other details in a consistent way like for entities.

Additionally you use two different plugins to place the block:

The second method, this is using custom blocks outside of the core block content plugin is not officially supported, because the pair of both are optimized to work together.

For the second method a custom entity might be a better choice (then of course one which has a template, which is standard for entities built by Drupal Console ).

I have noticed a discrepancy between Custom Block and Entity Block where one form gives you the view mode to show the block in, and the other does not (Custom Block).

Checking the linked code from the Custom Block plugin. It should show the view mode, if there is more than one to choose from:

$form['view_mode'] = [
  '#type' => 'select',
  '#options' => $options,
  '#title' => $this->t('View mode'),
  '#description' => $this->t('Output the block in this view mode.'),
  '#default_value' => $this->configuration['view_mode'],
  '#access' => (count($options) > 1),
  • Oh, interesting. I don't think I have block view modes yet, I was confused because I was seeing view modes from nodes in an entity block, vs an actual in line block.
    – Kevin
    Commented Dec 13, 2017 at 16:52

I like to reuse basic block for a lot, so I added a List(text) field called "field_role" With this, I can reuse the basic block type in lots of places, each with unique templates. The following provides template suggestions:

function mymodule_theme_suggestions_block_alter(array &$suggestions, array $variables, $hook) {
  if (isset($variables['elements']['content']['#block_content'])) {
    /** @var \Drupal\block_content\Entity\BlockContent $content */
    $content = $variables['elements']['content']['#block_content'];
    $view_mode = $variables['elements']['content']['#view_mode'];
    if (isset($content->get('field_role')->getValue()[0]['value'])) {
      $role = $content->get('field_role')->getValue()[0]['value'];
      $suggestions[] = "block__block_content__{$role}";
      $suggestions[] = "block__block_content__{$role}__{$view_mode}";
      if ($label = $variables['elements']['#configuration']['label']) {
        $label = preg_replace("/[^a-zA-Z0-9\s]+/", "", trim(strtolower($label)));
        $label = str_replace(" ", "_", $label);
        $suggestions[] = "block__block_content__{$role}__{$label}";
        $suggestions[] = "block__block_content__{$role}__{$label}__{$view_mode}";

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.