diff --git a/core/modules/system/config/schema/system.schema.yml b/core/modules/system/config/schema/system.schema.yml index e34d375..322371d 100644 --- a/core/modules/system/config/schema/system.schema.yml +++ b/core/modules/system/config/schema/system.schema.yml @@ -335,6 +335,9 @@ block.settings.system_menu_block:*: level: type: integer label: 'Starting level' + follow: + type: boolean + label: 'Follow the active menu trail' depth: type: integer label: 'Maximum number of levels' diff --git a/core/modules/system/src/Plugin/Block/SystemMenuBlock.php b/core/modules/system/src/Plugin/Block/SystemMenuBlock.php index 83a2f85..ab89985 100644 --- a/core/modules/system/src/Plugin/Block/SystemMenuBlock.php +++ b/core/modules/system/src/Plugin/Block/SystemMenuBlock.php @@ -101,6 +101,13 @@ public function blockForm($form, FormStateInterface $form_state) { '#required' => TRUE, ); + $form['menu_levels']['follow'] = array( + '#type' => 'checkbox', + '#title' => $this->t('Make the starting level follow the active menu item.'), + '#default_value' => $config['follow'], + '#description' => $this->t('If the active menu item is deeper than the level specified above, the starting level will follow the active menu item. Otherwise, the starting level of the tree will remain fixed.') + ); + $options[0] = $this->t('Unlimited'); $form['menu_levels']['depth'] = array( @@ -131,6 +138,7 @@ public static function processMenuLevelParents(&$element, FormStateInterface $fo public function blockSubmit($form, FormStateInterface $form_state) { $this->configuration['level'] = $form_state->getValue('level'); $this->configuration['depth'] = $form_state->getValue('depth'); + $this->configuration['follow'] = $form_state->getValue('follow'); } /** @@ -152,6 +160,18 @@ public function build() { $parameters->setMaxDepth(min($level + $depth - 1, $this->menuTree->maxDepth())); } + // Adjust the root according to the current position in the menu + // in order to determine if we can show the menu subtree. + if ($level > 1 && $this->configuration['follow']) { + if (count($parameters->activeTrail) >= $level) { + $menu_root = array_values($parameters->activeTrail)[count($parameters->activeTrail) - $level]; + $parameters->setRoot($menu_root)->setMinDepth(1); + } + else { + return array(); + } + } + $tree = $this->menuTree->load($menu_name, $parameters); $manipulators = array( array('callable' => 'menu.default_tree_manipulators:checkAccess'), @@ -166,8 +186,9 @@ public function build() { */ public function defaultConfiguration() { return [ - 'level' => 1, + 'level' => TRUE, 'depth' => 0, + 'follow' => 0, ]; }