Custom Twig Templates

You may never need to create a custom Twig template given how much you can accomplish by nesting built-in templates, but there could come a time when your design idea is complex enough that a custom template would be an easier approach.

Step One: Create the Template File

Your template file will be placed in a "/templates/" directory under the root directory of your module or theme and will end with ".html.twig".  The name you give your template depends on what you are trying to accomplish

Overriding Templates

It is possible to create custom templates that override built-in templates for various parts of a website.  These are usually included in custom themes or subthemes, but could be used in a module as well.  One possible module use case is overriding the wrapper structure for a block.

Any overriding template must be named in a precise fashion so that Drupal will find it and use it.  See Dupal.org's Twig Template Naming Conventions page for more details.

Fully Custom Templates

For a template to be used by render arrays in your custom module code, the template should be given a unique name prefixed with your module's machine name for ease of identification and avoiding conflicts.

Step Two: Develop the Template

The easiest way to get started with the Twig templating language is by reading over some existing files and or introductory documentation.  Be sure to look at Drupal specific template files, as there could be differences in how they're assembled compared to stock Twig templates.

Step Three: Enable the Template

Templates put into a theme package's "/templates/" directory do not have to be enabled - they should be recognized as soon as the theme is enabled or caches are flushed.

Templates put into a module's "/templates/" directory are not automatically detected, so you have to give Drupal a helping hand by implementing the hook_theme function in your module's .module file (replace 'mymodule' with the machine name of your actual module).  Be sure to only use dashes (no underscores) in your template filename, and note that the template name given in the hook_theme function must be the same as the filename, but without the ".html.twig" part.

function mymodule_theme($existing, $type, $theme, $path) {
  return [
    'mymodule-template-name' => [
      'variables' => ['data' => NULL],
      /* Add a 'key' = 'default value' pair to 'variables' for each variable you want passed from
       * a render array to this theming template */
    ],
  ];
}

Note that for an overriding template, you may need to tell Drupal what kind of template you're registering:

function mymodule_theme($existing, $type, $theme, $path) {
  return [
    'block__inline_block__standard_content' => [
      'base hook' => 'block', 
    ], 
    'field__block_content__field_image__standard_content' => [
      'base hook' => 'field',
    ],
  ];
}