The Question:

In Drupal 8: How do I add a template override for a view block and have that twig file reside in a custom module - not my theme?

Further Information:

I have already created a custom module that creates a content type, imports data from an RSS feed and generates nodes into the content type it created. The module also contains a view YML file so that the view for my content type is created when the module is installed. The view only has one display which is a block.

I would like to create a template override for the block and house the template override within the module (rather than within my theme). The template override does the following:

  • Adds the appropriate classes to the block
  • Adds an image beside the block title when the title is displayed
  • Wraps the {{ content }} in a div with an appropriate class
  • Loads the custom module's library to apply CSS

The goal is to have a module that a non-technical person can install, assign a block to the desired region and have all the templates, CSS, JS, etc pull from the module. I don't want them to have to copy a template into their theme, etc. I want the block to be a view so that the user can use the Views UI to make any desired updates to the view block's fields, number of returns, etc.

I was able to get Drupal to recognize the template by using hook_theme_registry_alter() but the variables from the block are null. Both the {{ label }} and {{ content }} are null when I kint them in the template override.

Here is the hook_theme_registry_alter() code:

 * Implements hook theme_registry_alter
function MYMODULE_theme_registry_alter(&$theme_registry){
  $theme_registry['block__views_block__MYVIEW_block_1']['path'] = drupal_get_path('module','MYMODULE') . '/templates/';
  $theme_registry['block__views_block__MYVIEW_block_1']['template'] = 'block--views-block--MYVIEW-block-1';

It should be noted that when I used hook_theme_registry_alter() for a view page template override in my module it worked. My guess is that the variables were pulled from the page alias.

Please include detailed information because I am still learning about the various hooks and how variables are passed. Thanks in advance!

1 Answer 1


To get the same variables as a block template add it as base hook:

 * Implements hook_theme().
function mymodule_theme() {
  return [
    'block__views_block__MYVIEW_block_1' => [
      'render element' => 'elements',
      'base hook' => 'block',

Now you can place the twig template in mymodule/templates/, path and filename are discovered automatically.

  • I was also able to use this recommendation to override the views field template by returning something like this: 'views_view_field__my_view__my_display__field_my_field' => [ 'render element' => 'elements', 'base hook' => 'views field' ]
    – beltouche
    Commented Nov 8, 2019 at 22:19
  • I just had to do something like this again: 'views_view_table__my_view' => ['base hook' => 'views table'] (no "render elements" needed) allowed me to add a <tfoot> in my view.
    – beltouche
    Commented Dec 11, 2021 at 20:21

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.