0

I'm currently attempting to create a plugin where the user can choose what level of a menu to render regardless of what page they're on. I'm generating the form where the user can select the menu level here

public function blockForm($form, FormStateInterface $form_state) {
    $menu_name = 'main';

    $menu_tree = \Drupal::service('toolbar.menu_tree');

    $parameters = new \Drupal\Core\Menu\MenuTreeParameters();
    $tree       = $menu_tree->load($menu_name, $parameters);

    $manipulators = array(
        array('callable' => 'menu.default_tree_manipulators:checkAccess'),
        array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'),
        array('callable' => 'toolbar_menu_navigation_links'),
    );

    $tree = $menu_tree->transform($tree, $manipulators);
    $list = ['none' => $this->t('None')];
    foreach ($tree as $item) {
        $list += [$item->link->getPluginId()=> $item->link->getTitle()];
        if ($item->hasChildren) {
            foreach ($item->subtree as $subitem) {
                foreach ($subitem->subtree as $subitem_child) {
                    $list += [$subitem->link->getPluginId() => '-'.$subitem->link->getTitle()];
                    foreach ($subitem->subtree as $sub_subitem) {
                        $list += [$sub_subitem->link->getPluginId()=> '--'.$sub_subitem->link->getTitle()];
                    }
                }
            }
        }
    }

    $form        = [
        'menu'            => [
            '#type'          => 'select',
            '#title'         => $this->t('Top level of menu'),
            '#default_value' => $this->configuration['menu'],
            '#options'       => [
                $list,
            ],
        ],
    ];

    return $form;
}

This works, and the user can select the level of the menu they want, but I'm not sure what to use in order to render the menu at that level. I did see that I could get a plugin

    $menu_name  = 'main';
    $menu       = $this->configuration['menu'];
    $menu_tree  = \Drupal::service('toolbar.menu_tree');

    $parameters = new \Drupal\Core\Menu\MenuTreeParameters();
    $tree = $menu_tree->load($menu_name, $parameters);

    $manipulators = array(
        array('callable' => 'menu.default_tree_manipulators:checkAccess'),
        array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'),
        array('callable' => 'toolbar_menu_navigation_links'),
    );

    $tree = $menu_tree->transform($tree, $manipulators);
    foreach ($tree as $item) {
        var_dump($item->hasChildren);
        if ($item->hasChildren) {
            var_dump($item->link->getTitle().' - '.$item->link->getPluginId());
            foreach ($item->subtree as $subitem) {
                var_dump($subitem->link->getTitle().' - '.$subitem->link->getPluginId());
                foreach ($subitem->subtree as $subitem_child) {
                    var_dump($subitem_child->link->getTitle().' - '.$subitem_child->link->getPluginId());
                    var_dump($subitem_child->link->getTitle().' - '.$subitem_child->link);
                }
            }
        }
    }

I have the pluginID of the selected in the form, but I'm not sure how to make any use of that. I tried using $parameters->setRoot('818bf040-f12a-4915-835f-b9339eb7c828');

Where 818bf040-f12a-4915-835f-b9339eb7c828 in this case was the pluginid of the selected menu item, but that caused the menu to not return anything.

Is there a way to render a menu and set the root to a specified location inside that menu programmatically?

0

My solution was to loop through each menu item and see if its plugin id is the same as the supplied one, and return the menu item as soon as it finds one. (Hopefully plugin ids are not prone to changes after they've already been set)

    foreach ($tree as $item) {
        if ($menu_link_id == $item->link->getPluginId()) {
            $top_level_menu = $item;
            return $item;
        }
    }
|improve this answer|||||
0

Try the following:

$parameters->setRoot('menu_link_content:818bf040-f12a-4915-835f-b9339eb7c828');
|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.