0

I've created several block plugins each with their own block form. My goal is to make it so you can select what template to use based on a field in the blockForm. I understand that I can change a block template within the build function by specifying the '#theme' but that refers to the content. I want to change block.html.twig template being used that surrounds the content. I also understand that I can specify the block template by using the naming scheme like block--block-name.html.twig but I want to be able to select the template within a preprocess function. Below is my attempt.

In mytheme.theme I have

function mytheme_theme($existing,$type,$theme,$path){
    return [
        'wide_grid_block' => [
            'variables' => [
                'test' => 'Test default value',
            ],
        ]
    ];
}

function mytheme_preprocess_block(&$vars){
      $vars['#theme'] = 'wide_grid_block';
}

and in templates/block/wide-grid-block.html.twig I have

Testing: {{ test }}

I assumed the what should occur is that every block should use the wide-grid-block.html.twig file. But they're all still using block.html.twig.

How do I specify a custom block template in a preprocess function?

UPDATE: I've also tried using a theme_suggestions_block_alter hook but I get a white screen when attempting to do so

function alltechcom2017_theme_suggestions_block_alter(array &$suggestions, array $variables) {
$suggestions[0]= 'wide_grid_block';
}

And I've tried with and without the [0]

UPDATE 2: I've managed to add to the suggestions by using

$suggestions[] = 'wide_grid_block';

The issue I had before with the white screen was because the file was in the wrong location. So I know drupal can see it, I just need it to be the most desired one in the list of possible templates.

In the debug info I see

<!-- FILE NAME SUGGESTIONS:
   * block--product-selector.html.twig
   * wide-grid-block.html.twig
   x block.html.twig
-->

And I have a block.html.twig and a wide-grid-block.html.twig. Why is it using block.html.twig instead? It's acting as if my file doesn't exist. I looked at this https://sqndr.github.io/d8-theming-guide/theme-hooks-and-theme-hook-suggestions/theme-hook-suggestions.html and it appeared like I was on the right track.

UPDATE 3: I've added

function mytheme_theme($existing,$type,$theme,$path){
    return [
        'wide_grid_block' => [
            'path' => drupal_get_path('theme','mytheme').'/templates',
            'template' => 'wide_grid_block',
        ],
    ];
}

but still no luck

5
  • I'm afraid, as you already understand the naming schema, you have to use it.
    – 4uk4
    Commented Nov 1, 2017 at 21:47
  • There's no way to overwrite that? I need individual blocks to change on a case by case basis.
    – Amy
    Commented Nov 1, 2017 at 21:52
  • Also I already have it to the point where it's appearing in the file name suggestions.
    – Amy
    Commented Nov 1, 2017 at 21:59
  • Add to the suggestions block__wide_grid.
    – 4uk4
    Commented Nov 1, 2017 at 22:16
  • added $suggestions[] = 'block__wide_grid'; and made a block--wide-grid.html.twig file in the templates folder but still no luck.
    – Amy
    Commented Nov 1, 2017 at 22:26

2 Answers 2

1

I managed to get it working by using

function mytheme_theme($existing,$type,$theme,$path){
        return [
                'wide_grid_block' => [
                        'path' => drupal_get_path('theme','mytheme').'/templates',
                        'template' => 'wide-grid-block',
        'render element' => 'elements',
        'preprocess functions' => ['template_preprocess','template_preprocess_block','comment_preprocess_block','mytheme_preprocess_block'],
                ],
        ];
}

function mytheme_theme_suggestions_block_alter(array &$suggestions, array $variables) {
if($variables['elements']['#configuration']['id'] == 'page_title' || $variables['elements']['#configuration']['id'] == 'product_selector'){
        $suggestions[] = 'wide_grid_block';
}
2
  • 1
    With the name suggestion block__wide-grid you wouldn't need to redefine the block hook in hook_theme().
    – 4uk4
    Commented Nov 2, 2017 at 7:15
  • I made an attempt using that format but still had issues.
    – Amy
    Commented Nov 2, 2017 at 13:44
1

I just ran into a very similar issue, where theme suggestions were displaying my custom block template, and the template was present in my theme, but wasn't being used.

<!-- FILE NAME SUGGESTIONS:
   * block--my-custom-template.html.twig
   * block--views-block.html.twig
   x block.html.twig
-->

In my case, I wanted to add a template suggestion based on the tag (my-custom-template) of the view that the block is displaying:

function mytheme_theme_suggestions_block_alter(array &$suggestions, array $variables) {
  // Add Views tag suggestions for block templates
  if ($variables['elements']['#base_plugin_id'] == 'views_block') {
    $view = View::load($variables['elements']['content']['#view_id']);
    $suggestions[] = 'block__' . str_replace('-', '_', $view->get('tag'));
  }
}

Without the str_replace, the $suggestion is 'block__my-custom-template' when it needs to be 'block__my_custom_template' in order for the template to be found and called correctly.

I know it doesn't 100% match the original issue, but I wanted to share for others and for me when I come searching for this again in a year!

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.