How to override page.html.twig in module for my custom page

64 Views Asked by At

I have a custom page defined in routing with it's ControllerBase class. I want to override the whole page.html.twig for this page.

If I use hook_theme and define there 'page__test' => [...] it overrides page with my page--test.html.twig, but I don't have variables from ControllerBase class.

1

There are 1 best solutions below

0
Kien Nguyen On

To override the whole page.html.twig template for your custom page you can use the following approach:

  1. In your theme or custom module, implement hook_theme_suggestions_HOOK_alter to suggest a custom template for your page:
/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function my_theme_theme_suggestions_page_alter(array &$suggestions, array $variables) {
  // Check if this is your custom page.
  if (\Drupal::routeMatch()->getRouteName() == 'your.route_name') {
    // Suggest a custom template for the page.
    $suggestions[] = 'page__test';
  }
}
  1. Create a custom template file page--test.html.twig in your theme or module's templates directory, in this file you can access variables from ControllerBase class:
{# themes/custom/my_theme/templates/page--test.html.twig #}

<div class="layout-container">

  <header role="banner">
    {{ page.header }}
  </header>

  {{ page.primary_menu }}
  {{ page.secondary_menu }}

  {{ page.breadcrumb }}

  {{ page.highlighted }}

  {{ page.help }}

  <main role="main">
    <a id="main-content" tabindex="-1"></a>

    <div class="layout-content">
      {{ page.content }}
    </div>

    {% if page.sidebar_first %}
      <aside class="layout-sidebar-first" role="complementary">
        {{ page.sidebar_first }}
      </aside>
    {% endif %}

    {% if page.sidebar_second %}
      <aside class="layout-sidebar-second" role="complementary">
        {{ page.sidebar_second }}
      </aside>
    {% endif %}

  </main>

  {% if page.footer %}
    <footer role="contentinfo">
      {{ page.footer }}
    </footer>
  {% endif %}

</div>