Drupal 8: программный вывод меню в шаблоне

Для того чтобы организовать программный вывод меню в произвольном месте в шаблоне темы Drupal 8, придется написать свое Twig расширение. Для этого в кастомном модуле создадим файл modules/custom/src/Twig/RenderMenuExtension.php

Структура директорий

и поместим в него следущий код:

<?php
namespace Drupal\custom\Twig;

class RenderMenuExtension extends \Twig_Extension {

  /**
   * {@inheritdoc}
   * This function must return the name of the extension. It must be unique.
   */
  public function getName() {
    return 'render_menu_extension';
  }

  /**
   * @return array
   */
  public function getFunctions()
  {
    return [
      new \Twig_SimpleFunction('renderMenu', [$this, 'renderMenu'])
    ];
  }

  /**
   * Provides function to programmatically rendering a menu
   *
   * @param String $menu_name
   *   The machine configuration id of the menu to render
   *
   * @return Array
   */
  public function renderMenu(string $menu_name) {
    $menu_tree = \Drupal::menuTree();

    // Build the typical default set of menu tree parameters.
    $parameters = $menu_tree->getCurrentRouteMenuTreeParameters($menu_name);

    // Load the tree based on this set of parameters.
    $tree = $menu_tree->load($menu_name, $parameters);

    // Transform the tree using the manipulators you want.
    $manipulators = array(
      // Only show links that are accessible for the current user.
      array('callable' => 'menu.default_tree_manipulators:checkAccess'),
      // Use the default sorting of menu links.
      array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'),
    );
    $tree = $menu_tree->transform($tree, $manipulators);

    // Finally, build a renderable array from the transformed tree.
    $menu = $menu_tree->build($tree);

    $menu['#attributes']['class'] = 'menu ' . $menu_name;

    $renderer = \Drupal::service('renderer');
    return ['#markup' => $renderer->render($menu)];
  }

}

Затем в сервисном конфиге модуля modules/custom/custom.services.yml нужно прописать следующее:

services:
  custom.render_menu_extension:
      class: Drupal\custom\Twig\RenderMenuExtension
      tags:
        - { name: twig.extension }

Теперь в Twig шаблоне можно программно вывести любое меню:

{{ renderMenu('main') }}

 

Комментарии