I'm trying to follow this post to turn my menu tree into an array I can more easily work with.

When I run my code and look at $filteredArray I get:

title: *Name here*
url_obj: {}
has_children: true

I'm mostly working in THEME.theme page in:

function THEME_page_attachments_alter {
  $filteredArray = array();
  $menu_tree_service = \Drupal::service('menu.link_tree');

  $menu_parameters = new \Drupal\Core\Menu\MenuTreeParameters();

  $tree = $tree = $menu_tree_service->load('main', $menu_parameters);
  foreach ($tree as $item) {
    $itemObject = (object) ['title' => '', 'url_obj' => '', 'has_children' => ''];

    $itemObject->title = $item->link->getTitle();
    $itemObject->url_obj = $item->link->getUrlObject();
    $itemObject->has_children = $item->hasChildren;

    array_push($filteredArray, $itemObject);
  $page['#attached']['drupalSettings']['mobileMenu']['menuTree'] = $tree;
  $page['#attached']['drupalSettings']['mobileMenu']['filteredArray'] = $filteredArray;

So it looks like it is grabbing the pages and returning them and looking at the docs I should be able to just call $item->link->getUrlObject(); to get the url so I'm not sure where I am going wrong.

Any pointers are appreciated, thanks!


Thanks to @stevekeiretsu for the pointers I have updated my code to:

  1. Stringify getUrlObject:

    $itemObject->url_obj = $item->link->getUrlObject()->toString();

  2. JSON encode $filteredArray before it is added to Drupal Settings:

    $page['#attached']['drupalSettings']['mobileMenu']['filteredArray'] = json_encode($filteredArray);

I am still getting an empty url for the url_obj and I also noticed that on $tree's menu items each had an empty object for 'link', so that I could see that leading to an empty url but then I do not understand why I am able to get the title of each of the menu items.

Thanks again!

Edit 2

It looks like this might have been an existing issue: https://www.drupal.org/project/drupal/issues/2642602

I'm really new to Drupal so I'm not sure about this.

  • 1
    Firstly you're adding an array of PHP objects ($itemObjects) to drupalSettings. You need to add JSON. Try json_encode($filteredArray) at the end there. Similarly, JSON-land isn't going to know what to do with a drupal Url object either. Try $item->link->getUrlObject->toString() to get the raw URL as a string, suitable for JSON encoding. Commented Mar 25, 2020 at 18:16
  • Thanks for that, brand new to Drupal so that helps a lot. I did what you expected and am seeing "[{"title":"Individuals","url_obj":"" ..." for $filteredArray. I did notice that on the $tree object when I look at individual menu items "link" is an empty object. Could it be that because I'm developing locally these pages just do not have a "link" property? Or what could make it return empty?
    – av0000
    Commented Mar 25, 2020 at 18:51
  • Not sure I'm afraid. As far as I can tell perusing the docs your code is following all the APIs, so perhaps it is that because of that bug you've linked. When you say "I did notice on the $tree object" are you inspecting that in phpstorm / xdebug? What about inside the foreach, does the $item have a null link property? Commented Mar 26, 2020 at 0:07
  • your hook not implementing good the THEME_page_attachments_alter should be function THEME_page_attachments_alter(array &$page) don't know if just a mistake, but you should have a $page passed by reference to change it in the hook. I tested your code with the update it's working good
    – berramou
    Commented Mar 27, 2020 at 20:05


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.