Попытка выделить текущий пункт меню в Drupal 8 с помощью hook_preprocess_menu

У меня есть функция ниже для создания активной функциональности следа. Так что, если бы я имел / blog в качестве «родителя» и пост / blog / mypost, когда на mypost ссылка на блог показывалась бы как выделенная. Я не хочу делать пункты меню для всех сообщений в блоге. Проблема заключается в том, что при включенном кэшировании (без использования settings.local.php и отключенной отладки) getRequestUri не изменяется на некоторых страницах. Вроде бы кешируется в зависимости от страницы. Он работает нормально с отключенным кэшированием страниц, но я бы хотел, чтобы это работало с кэшированием. Есть ли лучший способ проверить текущий путь и применить активный класс?

function mytheme_preprocess_menu(&$variables, $hook) {
if($variables['theme_hook_original'] == 'menu__main'){
$node = \Drupal::routeMatch()->getParameter('node');
if($node){
$current_path = \Drupal::request()->getRequestUri();
$items = $variables['items'];
foreach ($items as $key => $item) {
// If current path starts with a part of another path i.e. a parent, set active to li.
if (0 === strpos($current_path, $item['url']->toString())) {
// Add active link.
$variables['items'][$key]['attributes']['class'] .= ' menu-item--active-trail';
}
}
}
}
}

Я также попытался поместить это в модуль, чтобы попытаться выяснить, могу ли я получить текущий путь, а затем выполнить логику веток в меню — шаблон main.twig.html, но у меня та же проблема.

function highlight_menu_sections_template_preprocess_default_variables_alter(&$variables) {
$variables['current_path'] = $_SERVER['REQUEST_URI'];
}

1

Решение

После очень долгого пробования всевозможных вещей я нашел отличный модуль, который решает именно эту проблему. Устанавливайте и работайте, а не настройку, это просто работает:

https://www.drupal.org/project/menu_trail_by_path

Стабильные версии для D7 и D8.

2

Другие решения

Я попытался объявить активный путь как часть пользовательского блока меню, и даже тогда мой объявленный след кэшируется. Предполагая, что это связано с «Нет способа установить активную ссылку — переопределите службу, если вам нужно больше контроля». заявление в этот список изменений, хотя почему MenuTreeParameters-> setActiveTrail () существует чья-то догадка.

Для любопытных (и для меня, когда я буду искать это позже!), Вот функция build () моего блока:

public function build() {
$menu_tree = \Drupal::menuTree();
$parameters = new MenuTreeParameters();
$parameters->setRoot('menu_link_content:700c69e6-785b-4db7-be49-73188b47b5a3')->setMinDepth(1)->setMaxDepth(1)->onlyEnabledLinks();

// An array of routes and menu_link_content ids to set as active
$define_active_mlid = array(
'view.press_releases.page_1' => 385
);
$route_name = \Drupal::request()->get(RouteObjectInterface::ROUTE_NAME);
if (array_key_exists($route_name, $define_active_mlid)) {
$menu_link = \Drupal::entityTypeManager()->getStorage('menu_link_content')->loadByProperties(array('id' => $define_active_mlid[$route_name]));
$link = array_shift($menu_link);
$parameters->setActiveTrail(array('menu_link_content:' . $link->uuid()));
}

$footer_tree = $menu_tree->load('footer', $parameters);
$manipulators = array(
array('callable' => 'menu.default_tree_manipulators:checkAccess'),
array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'),
);
$tree = $menu_tree->transform($footer_tree, $manipulators);
$menu = $menu_tree->build($tree);

return array(
'menu' => $menu,
);
}
0

[добавив новый ответ, так как это совершенно другой подход, чем мой предыдущий]

Если приемлемо решение на основе CSS, похоже, это работает нормально:

.page-node-type-press-release {
a[data-drupal-link-system-path="press-room/press-releases"] {
// active CSS styles here
}
}
0
По вопросам рекламы [email protected]