3

I'm looking to provide a template for a custom block in my custom module. There are two ways to go about this: provide a template for just the block's content, or provide a template that extends block.html.twig. I've returned empty-handed in my search for a best practice. Let me clarify the two options to provide a template for my custom module's block:

Option 1: provide a template for the block's content

<?php
/**
 * Implements hook_theme().
 */
function mymodule_theme($existing, $type, $theme, $path) {
  return array(
    'mymodule' => array(
      'variables' => array('var' => 'test'),
    ),
  );
}
?>

The template named mymodule.html.twig looks like this:

This is my content: {{ var }}

Option 2: extend block.html.twig

<?php
/**
 * Implements hook_theme().
 */
function mymodule_theme($existing, $type, $theme, $path) {
  return array(
    'block__mymodule' => array(
      'base hook' => 'block',
      'variables' => array('var' => 'test'),
    ),
  );
}
?>

The template named block--mymodule.html.twig looks like this:

{% extends "block.html.twig" %}
{% block content %}
This is my content: {{ var }}
{% endblock %}

Looking for a best practice

The documentation on Twig Template naming conventions is quite clear on this: for a block, the name should be block--module.html.twig. However, is that the filename a themer would use to overwrite my block content (option 1) or is it the filename I should use for the template I provide for my custom module (option 2)? I haven't found a clear answer on this so as far as I can see there's no best practice on this yet.

2 Answers 2

3

I would prefer option 1. Theme the inside of a block in a custom template with custom variables or build a render array with render elements. Use the block template only to theme the outside of the block, for example add a wrapper div.

Option 2 is not a good idea, because it uses this block template:

{% extends "block.html.twig" %}
{% block content %}
This is my content: {{ var }}
{% endblock %}

Normally a block template looks like this:

{% extends "block.html.twig" %}
{% block content %}
This is my content: {{ content }}
{% endblock %}

By ignoring {{ content }} in a block template no cache metadata can bubble up. See https://www.previousnext.com.au/blog/ensuring-drupal-8-block-cache-tags-bubble-page

You could try to add the cache metadata with block methods. But this is not good practice, because if later someone tries to add block content and is not aware of that the block template doesn't use the base hook variables this person will have a hard time debugging this.

2

I would prefer to use option 2, but depending on the use case without the {% extends... %} part and possibly at some template suggestions just in case that block is used in various contexts where the additional HTML is needed.

1
  • You're right about the use case of various contexts. If I provide a template for just the content, people can copy mymodule.html.twig to their theme's directory, or create their own block--mymodule.html.twig template, chosing to extend block.html.twig or not. If I go for option 1, I might implement hook_theme_suggestions_HOOK_alter. Commented Jan 5, 2017 at 16:29

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.