Score:0

How to get translated menu link entity

cn flag

I have a headless Drupal 9 solution and I'm currently working on i18n of the whole site.

I've managed to do everything except menus. The content translation core module is installed and setup correctly. I have all the menu items translated. This a snippet of the code:

  $parameters = new MenuTreeParameters();
  $parameters->onlyEnabledLinks();

  // Get drupal menu tree.
  $menu_tree = \Drupal::menuTree();

  // Load the menu tree.
  $main_menu_tree = $menu_tree->load('main', $parameters);

...

$manipulators = [
  ['callable' => 'menu.default_tree_manipulators:checkNodeAccess'],
  ['callable' => 'menu.default_tree_manipulators:checkAccess'],
  ['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
];

$tree = $menu_tree->transform($main_menu_tree, $manipulators);

...

  foreach ($tree as $key => $menu_tree_element) {
    $menu_object = $this->generateSingleMenuObject($menu_tree_element, $max_depth);

    array_push($menu_array, $menu_object);
  }

The 'generateSingleMenuObject' function is where I'd expect to somehow get the objects in a certain language. Here's how the function starts

// Get link from menu tree element.
$menu_tree_element_link = $menu_tree_element->link;

// Get url object from link.
$menu_url_object = $menu_tree_element_link->getUrlObject();

// Create dummy object for storing data.
$menu_object = new stdClass();

// Get id and label.
$menu_object->id = $menu_tree_element_link->getDerivativeId();
$menu_object->label = $menu_tree_element_link->getTitle();

// Get href.
$menu_object->href = $menu_url_object->toString();

I've tried some of the standard options that worked on other entities but without luck.

This is basically the same question as this one.

The only thing I need is the translated menu label. What am I missing? This really sounds like it should be a relatively simple ask. Thank you!

Score:0
pa flag

It seems like you're building a custom solution to generate menu items for a headless Drupal site, and you're encountering difficulties with retrieving translated menu labels. In Drupal 9, using the right services and methods is crucial to achieving accurate translations. To get the translated menu labels for each language, you can follow these steps:

  1. Use the Translation Manager: The MenuLinkManagerInterface provides a method to load menu links with translations. Using the MenuLinkManagerInterface::loadLinks() method with the appropriate parameters, you can load translated menu links.

  2. Loop Through Translated Links: Once you have the translated menu links, you can loop through them and extract the translated label for each link. This ensures that you get the labels in the correct language.

Here's how you can modify your code to achieve this:

use Drupal\Core\Menu\MenuLinkManagerInterface;
use Drupal\Core\Menu\MenuTreeParameters;
use Symfony\Component\DependencyInjection\ContainerInterface;

class MyMenuService {

  protected $menuLinkManager;

  public function __construct(MenuLinkManagerInterface $menuLinkManager) {
    $this->menuLinkManager = $menuLinkManager;
  }

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('menu.link_manager')
    );
  }

  public function generateMenu() {
    $parameters = new MenuTreeParameters();
    $parameters->onlyEnabledLinks();

    // Load the menu tree.
    $main_menu_tree = $this->menuLinkManager->loadLinks('main', $parameters);

    // Add your manipulators and transform the tree.
    // ...

    $menu_array = [];

    foreach ($tree as $key => $menu_tree_element) {
      $menu_object = $this->generateSingleMenuObject($menu_tree_element, $max_depth);

      array_push($menu_array, $menu_object);
    }

    // ...
  }

  protected function generateSingleMenuObject($menu_tree_element, $max_depth) {
    // ... your existing code ...

    // Load the translated link.
    $translated_menu_tree_element_link = $this->menuLinkManager->loadLink($menu_tree_element->link->getPluginId(), $menu_tree_element->link->getMenuName(), $menu_tree_element->link->getPluginDefinition());

    // Get the translated title.
    $translated_label = $translated_menu_tree_element_link->getTitle();

    // Set the translated label in the menu object.
    $menu_object->label = $translated_label;

    // ... rest of your code ...
  }
}

By using the MenuLinkManagerInterface methods to load and handle menu links, you ensure that you get the translated menu labels for each language. This approach should work well with your headless Drupal solution. Just make sure you have the necessary dependency injections set up and the right services used in your class.

frajer avatar
cn flag
Hi Z CHAMP, thanks for you response. You are right, it's a Drupal 9 headless solution but I'm afraid your answer isn't as helpful as I hoped it would be. By looking into it I've found the menu.link_manager service doesn't exist and even if it did the MenuLinkManagerInterface doesn't have the functions you are suggesting (loadLinks() and loadLink)? Could you elaborate a bit further or tell me if I'm getting something totally wrong here? Thanks!
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.