0

I've got a bizarre issue where my the render array from my block plugin's build() method doesn't seem to be properly interpreted by the template. I've got the following setup.

function my_module_theme(){
  return [
    'block__my_module__user_header' => [
      'render element' => 'children', // also tried without this
      'variables' => [
        'tabs' => NULL,
        'user' => NULL,
      ],
    ],
  ]
}

and my block plugin class

public function build() {

  $render_array = [
    '#theme' => 'block__my_module__user_header',
    '#tabs' => $this->getTabs(), // returns an array of data to handled in twig
    '#cache' => [
      'contexts' => [
        'route',
        'user',
      ],
    ],
  ];

  if ($user = $this->getContextValue('user')) {
    $render_array['#cache']['tags'] = $user->getCacheTags();
    $render_array['#user'] = $user;
  }

  return $render_array;
}

But then, when I inspect the variables in theme_preprocess_block(), all of that render array information from build() is sitting in $variables['content']. Same in the actual twig template, and same result if I remove ['#cache'] from build(). I'd expect to be able to access {{ tabs }} directly, but instead the data is sitting in {{ content['#tabs'] }}. Aside from that inconvenience, it also means that any cache tags/contexts I try to set in build() don't end up in the actual render array so they're completely ignored, which is a problem because the "tabs" as rendered in twig are dependent on this context.

I'm completely perplexed, as the same pattern works fine for hook_theme/block plugins in some of my modules, but this issue crops up in other modules.

1 Answer 1

1

This is how block templates work, they render the variable content.

{{ content }}

Your code though is using a block template inside of a block, which doesn't make sense, because the block template is wrapped around the block by Drupal automatically. You probably want to build the inside of the block like a controller output by using a custom template not derived from a block template, which you do when you don't start the template name with block__.

See https://www.drupal.org/docs/theming-drupal/twig-in-drupal/create-custom-twig-templates-for-custom-module

1
  • Thanks, you're right, that all makes. I was conflating a few different things and confusing myself. I was defining the block__ template bit then trying to treat the variables like I would in a generic hook_theme() template implementation (which obviously doesn't work).
    – Mrweiner
    Jul 21, 2020 at 22:42

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.