Drupal Answers is a question and answer site for Drupal developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm constructing a site that has 6 localized versions (English, German, Russian etc.). So the site is supposed to have a localized navigation menu with a common structure across the languages.

I've decided that importing menu items though several Drupal API calls would be the quickest way to create the menu structure I need. So I've learned how to save menu links with menu_link_save() function and they even get their language field set correctly... but those imported items in different languages mix with each other and get displayed all togeher :-(

When I open and save some imported menu item through Drupal administrative interface it starts behaving properly and gets displayed only when the site is in it's language. Also the 'options' database field for this item becomes populated with some additional data compared to other imported items.

So my question is: what i18n API or some other function should i call to save menu items with all needed options? Maybe there is a better way to painlessly import menus?

Thanks in advance!

share|improve this question

You dont need to play directly with i18n. All you need is the correct configuration. It also has a difference between translated and localized items. Translated items may point to different pages and may have different description (besides other customization). Localized item is the same item with just a different title on the menu for each language.

I think you want a translated item. Here is the recipe with some comments:

 $menu_item = array(
    'link_title' => 'The menu link title',
    'menu_name'  => 'machine-name-of-the-menu', // It uses '-', not '_'
    'customized' => 1, // Must be 1 in order to not dispaly the link in any language
    'link_path'  => 'node/' . $node->nid, // menu_link_save() does not like aliases. Then 'nid' is used
    'language'  => 'en', // language is required in order to make the item translatable
  $mlid = menu_link_save($menu_item); // You don't need to receive it in a variable
  $ml = menu_link_load($mlid); // I'm loading $mlid just to display the result and verify it
  print_r($ml); // Use print_r() only if you are testing on the block "Execute PHP"

I had a hard time to figure out the need of 'customized' and also the path alias issue.

share|improve this answer
Thanks for this. I used this code in a snippet drupal.org/node/1782548#comment-9092667 – JamesWilson Aug 25 '14 at 23:38
I turned it into a gist: gist.github.com/338e44cd13afba682dcd – JamesWilson Aug 26 '14 at 0:00

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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