그래서 사용자 정의 블록을 만들고 빌드 방법에서 변환기가 추가 된 메뉴를 출력 하여이 작업을 수행 할 수있는 코드를 알아 냈습니다. 이것은 블록의 메뉴를 가져 와서 변환기를 추가하는 방법을 알아내는 데 사용되는 링크입니다 : http://alexrayu.com/blog/drupal-8-display-submenu-block . 내 결과 build()는 다음과 같습니다.
$menu_tree = \Drupal::menuTree();
$menu_name = 'main';
// 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'),
// Remove all links outside of siblings and active trail
array('callable' => 'intranet.menu_transformers:removeInactiveTrail'),
);
$tree = $menu_tree->transform($tree, $manipulators);
// Finally, build a renderable array from the transformed tree.
$menu = $menu_tree->build($tree);
return array(
'#markup' => \Drupal::service('renderer')->render($menu),
'#cache' => array(
'contexts' => array('url.path'),
),
);
변환기는 서비스이므로 intranet.services.yml인트라넷 모듈에 추가하여 정의한 클래스를 가리 켰습니다. 이 클래스에는 세 가지 메소드가 있습니다. removeInactiveTrail(), getCurrentParent()사용자가 현재있는 페이지의 상위를 가져 오기 위해 호출 stripChildren()했으며 현재 메뉴 항목의 하위 항목과 해당 형제로만 메뉴를 제거했습니다 (예 : 활성 트레일에서 t).
이것은 다음과 같습니다
/**
* Removes all link trails that are not siblings to the active trail.
*
* For a menu such as:
* Parent 1
* - Child 1
* -- Child 2
* -- Child 3
* -- Child 4
* - Child 5
* Parent 2
* - Child 6
* with current page being Child 3, Parent 2, Child 6, and Child 5 would be
* removed.
*
* @param \Drupal\Core\Menu\MenuLinkTreeElement[] $tree
* The menu link tree to manipulate.
*
* @return \Drupal\Core\Menu\MenuLinkTreeElement[]
* The manipulated menu link tree.
*/
public function removeInactiveTrail(array $tree) {
// Get the current item's parent ID
$current_item_parent = IntranetMenuTransformers::getCurrentParent($tree);
// Tree becomes the current item parent's children if the current item
// parent is not empty. Otherwise, it's already the "parent's" children
// since they are all top level links.
if (!empty($current_item_parent)) {
$tree = $current_item_parent->subtree;
}
// Strip children from everything but the current item, and strip children
// from the current item's children.
$tree = IntranetMenuTransformers::stripChildren($tree);
// Return the tree.
return $tree;
}
/**
* Get the parent of the current active menu link, or return NULL if the
* current active menu link is a top-level link.
*
* @param \Drupal\Core\Menu\MenuLinkTreeElement[] $tree
* The tree to pull the parent link out of.
* @param \Drupal\Core\Menu\MenuLinkTreeElement|null $prev_parent
* The previous parent's parent, or NULL if no previous parent exists.
* @param \Drupal\Core\Menu\MenuLinkTreeElement|null $parent
* The parent of the current active link, or NULL if not parent exists.
*
* @return \Drupal\Core\Menu\MenuLinkTreeElement|null
* The parent of the current active menu link, or NULL if no parent exists.
*/
private function getCurrentParent($tree, $prev_parent = NULL, $parent = NULL) {
// Get active item
foreach ($tree as $leaf) {
if ($leaf->inActiveTrail) {
$active_item = $leaf;
break;
}
}
// If the active item is set and has children
if (!empty($active_item) && !empty($active_item->subtree)) {
// run getCurrentParent with the parent ID as the $active_item ID.
return IntranetMenuTransformers::getCurrentParent($active_item->subtree, $parent, $active_item);
}
// If the active item is not set, we know there was no active item on this
// level therefore the active item parent is the previous level's parent
if (empty($active_item)) {
return $prev_parent;
}
// Otherwise, the current active item has no children to check, so it is
// the bottommost and its parent is the correct parent.
return $parent;
}
/**
* Remove the children from all MenuLinkTreeElements that aren't active. If
* it is active, remove its children's children.
*
* @param \Drupal\Core\Menu\MenuLinkTreeElement[] $tree
* The menu links to strip children from non-active leafs.
*
* @return \Drupal\Core\Menu\MenuLinkTreeElement[]
* A menu tree with no children of non-active leafs.
*/
private function stripChildren($tree) {
// For each item in the tree, if the item isn't active, strip its children
// and return the tree.
foreach ($tree as &$leaf) {
// Check if active and if has children
if ($leaf->inActiveTrail && !empty($leaf->subtree)) {
// Then recurse on the children.
$leaf->subtree = IntranetMenuTransformers::stripChildren($leaf->subtree);
}
// Otherwise, if not the active menu
elseif (!$leaf->inActiveTrail) {
// Otherwise, it's not active, so we don't want to display any children
// so strip them.
$leaf->subtree = array();
}
}
return $tree;
}
이것이 최선의 방법입니까? 아마 아닙니다. 그러나 적어도 비슷한 것을 해야하는 사람들에게는 시작 점이됩니다.