After reviewing language support and translation for many of Drupal's pieces, we arrived at a pretty complex question, building multilingual navigation. The question is especially of importance because we often need to put translated content in menus, and the cross of translation of content and translation of menus can easily get us into the woods. Let's build some simple solutions for different use cases to see how to think of multilingual menus.
Let's consider we don't need to translate our menu per say, we need different menu structures for different languages. For example, we have an extensive menu structure in Hungarian and need a few pages in English with a small menu additionally. Without reaching for any menu translation solution, we could achieve this by just creating two separate menus in Administration » Structure » Menus. I choose to name these "Hungarian menu" and "English menu" for the sake of our discussion.

These menus will not show up in the node form though by default. To make them appear for easy association to posts, we should edit the content types involved and allow them to show these menus when nodes are created. Note that both menus will show up regardless of language of the node. Make sure to always click in language support for the node types (as explained earlier in the series) on the content type page.

Since the menus are exposed as blocks to our users, we can just enable both navigation blocks, place them under each other on the site and then reach back to what we learned about language based block visibility earlier in the series and set both blocks to only show for the respective languages.

This is the simplest solution to use, and only involves already existing pieces we knew. It does require us to have separate nodes for separate languages even if they are translations of the same content, but direct menu item editing on the node page and full control on language specific menus is what we get in return.
Now, Internationalization module can do much more and add actual language awareness to menus, so let's go ahead and enable the Menu translation module (part of the i18n module suite). This will also require the translation set module, which we'll talk about briefly.

Enabling this module adds two noticeable features to the menu editing page. First of all, we can translate the menu itself. Since menus themselves have a textual name and description, those would need translation. In our case, we use the menus still for separate languages, so we are fine not going there.
Then there is a set of three multilingual options we can choose from that apply to the items themselves inside the menu. The first option says we'll not want to associate language information to items, the second says we want to decide on a per item basis and the last means we want to attach a language to this menu as a whole so it would apply language visibility to the menu items. Let's choose the second option to show how different menus can be relate items to each other.
As shown above, I've created two About us pages for Hungarian and English respectively. Block visibility is showing the right language version of the menu as expected, but the language switcher block navigation does not work to lead to the menu item in other languages. To make this work with separate menu items, we need to tell the system that the two items belong to a translation set.
Let's go edit one of the menu items, in my case the Hungarian About us page. It would show at the bottom that the language is Hungarian and that This menu item belongs to a node, so it will have the same language as the node and cannot be localized. This merely means that we cannot translate the menu title text itself. What we can do however, is to relate the item to another item. This happens in the standard translate tab on the page which lets you either create a new menu item for the translation (add translation link) or associate an existing menu item (translations fieldset).

Let's pick the English About us page to relate to the Hungarian one in the fieldset! By establishing this association, we made connection between the two previously separate menu items, so the About us items in the two languages are now connected. If you hit one and click on the other language in the language switcher block, you get to the node in the other language.
Similarly, if you have Contact module enabled, you can add an item titled Contact us to your menu pointing to the contact form. You set the language of the item proper to your menu, and you get a Translate tab for the item where you can associate the menu item as translation with another one. Here you can use the add translation menu item and create a new menu item in the other menu. The path will be pre-filled and the language will be pre-selected. Make sure to pick the right parent menu though. At the end what you get is interlinked contact form menu items in your two menus.

Wait, wait! Why did I need to create two separate menu items for the contact form with the same path? Well, I had two menu structures to maintain, so I needed a copy of the item in both menus. However, in many cases, we need an identical or nearly identical menu structure for menus in different languages, and maintaining two copies is just too tedious. Localizable menu items help in that case.
Let's create a new menu called Multilingual menu for this use case. Choose Translate and Localize for this menu as well, however, this time we'll use the whole set of benefits on offer. Let's start this time by adding the Contact us item.
Bear with me because this is not very intuitive on the UI. The Translate and Localize option explains how it works as Menu items with language will allow translations. Menu items without language will be localized. We've used the first portion of the feature set above. Now we'll make use of the second part. To use localized menu items (items shared between languages with translated title and description), we need to add the Contact us menu item as Language neutral. Yes, this is pretty counter-intuitive.
What this actually means for i18n_menu is that we want to use localization instead of associating other menu items as translations. (I think this language option could use a better name). Because configuration localization always happens in Drupal from the site's default language to other languages, make sure you create the menu item in the site default language. Good quirk to now! Again, make sure to choose Language neutral for the menu item when created.

This will open up a Translate tab that at first glance will look very similar to the previous one. However, note that we don't have the option to associate existing menu items, and we have a translate action that actually lets us translate the contact menu item title and description instead of creating yet another menu item.
Finally, let's make this menu block appear on our pages, and you'll notice that the Contact us item will appear localized to the current language at hand and always point to the current language version of the page. Bingo! We just built a localized menu item where we did not need two menus or even two menu items.
Now how can we build in the two nodes for our About us page in this menu? The menu item localization does not allow to make the path different per language (it is specifically built to have same menu items appear translated), but we do have separate nodes, and therefore separate paths, so we'd need to include both menu items properly filtered for language. For this, we just replicate what we did above.
We add a menu item for node/1 (which in my case was the Hungarian page), mark it Hungarian in the menu and add a translation as a separate menu item (but this time in the same menu!), that would say About us and point to node/2 (in my case the node for the English page). Looks how we reused the same practice to have menu items in the same menu only apply to certain languages. That is why languages are specified on the menu item level. So we have a theoretically three item menu, of which only two would show at once. The Hungarian version of the About us item and the Contact us link in Hungarian or the About us page in/for English and the Contact us link properly translated to English.
So the the difference between menu item translation and menu item localization is that translation relates separate items together in a translation set and localization uses the same menu item but translates the title and description. We need to have a translation set when the paths are different, we can use localization, when they are not.
Now we have both the Multilingual menu and the two other menus referencing the About us page nodes. This makes it impossible to maintain those menu items from the nodes themselves (because the node forms only maintains one menu item per node), but the reason to have these many menus with the same pages referenced was just for the sake of demonstration. On an actual site you'd choose one or the other method for your menus based on how different you want to make your menus.
We still needed to create two separate menu items for the nodes, regardless of whether it was in the same menu or two separate menus. This stems from the basic fact that they are separate nodes with separate paths. If you are an avid reader of my previous pieces on multilingual Drupal 7, you know the solution to make these two nodes/paths one. Yes, Entity translation module will let you do that. Read more in the Node translation tutorial.
Now if you enable your content type for multilingual support with entity translation, you'll be able to create a menu item from the node page and translations for the nodes, but it will not work quite right. If you create the node in Hungarian and the translation in English, the item will only ever show up in the Hungarian rendition of the menu. This comes from the description for menu item language support that we explained above. The menu item will inherit the main node language and will only display for that language.
To solve this, we'd need to exploit the localization feature as explained for the contact page, which would require the menu item is saved Language neutral to be localized. Since the language is tied to the node, and cannot be changed on the menu item, we need to delete the menu item and create a new one, setting it to language neutral. This will suddenly let us translate the menu item to different languages, and it will show up regardless of language with the right translation. That is, until you save the node again, which would reset the menu language information and tie it to a language again.
There are clearly various points in this interaction that would need both bugfixes and usability improvements. To avoid the reset happening and the buggy display of menu items, you can work around the node path limitation by creating your node menu items manually and pointing them to node/$nid/view (instead of just node/$nid). The /view suffix still makes it point to the same page, however both Drupal and i18n looses all automation for relating it to the node, so you can freely specify the language to be neutral and translate the menu items. Also, since as said above for "language neutral" menu items, the language used for localization is the site's default language, make sure you create the menu item using the title of the node applicable to that language and translate from there to other languages.
This would not let you manage any menu items on the node forms, all menu item management would be done direct on the menu interface, but you get less menu items with more flexibility and no forced magic where you don't need it.
In summary, the different approaches explained above result in nodes, pages and menus created so (green arrows between menu items show translation set relations between items):

(View the full drawing at https://docs.google.com/drawings/d/166bGwkGdgS4oqXRd4hKA1gz1iQPn5VnQ90-s...)
I hope this much delayed piece of tutorial helped shed some light on menu language solutions. Even though building navigation is a number one concern for site builders, this is clearly a less developed area and some non-intuitive configuration options and language specifics are to be kept in mind to navigate the waters of menu building. We went from two totally separate menus to integrating some items into one and then all items to standalone localized pieces. These techniques are to be combined in real project where sometimes you need to build completely separate menus per language and other times make menus almost identical with the least effort possible.
You can read my set of articles on Drupal 7 multilingual site construction at http://hojtsy.hu/multilingual-drupal7.
Happy site building!
Comments
Robert Douglass (not verified)
Sun, 11/20/2011 - 13:12
Permalink
Should menus and menu items be entities?
If menus and menu items were entities, and the content (Name, Description for menus, Title for menu items) were Fields, would that make it any simpler to settle on a translation paradigm for them? Would it eliminate the need for a separate toolset?
Gábor Hojtsy
Sun, 11/20/2011 - 16:01
Permalink
Yesss
Yes, see and support http://drupal.org/node/916388 please. Thanks!
Quentin DELANCE (not verified)
Sun, 11/20/2011 - 20:03
Permalink
It makes sense for menu items to be entities IMO
From my point of view (Drupal user, admin point of view, I am not a developer), it would make sense as we usualy need to enhance default menu entries with things like images, extra properties to make clickable or not, appear in site map or not and so on.
Actually we tend to use taxonomies when we need to build a complex menu system, as they are fieldables...
podarok (not verified)
Mon, 11/21/2011 - 12:38
Permalink
nice
wow
like to read it in such structured way
FatherShawn (not verified)
Wed, 12/14/2011 - 20:55
Permalink
Menu links to nodes with entity translation
This info was just what I needed. I've been chasing my tail on this!!
Dan (not verified)
Thu, 01/05/2012 - 17:02
Permalink
support for views and breadcrumbs
Firstly thanks for this great series of articles providing a detailed overview of i18n suite of modules. I could get everything working more or less apart from the entity translation. Perhaps this needs to be set up from the start but when I tries to enable it it seemed to conflict. Or perhaps the way this works has changed since you wrote this article?
My question really is concerning the use of views and i18n suite. I have a site that currently uses 2 languages (phase1) that will be later expanded to support more languages. Therefore I would like to avoid using a different menu for each language.
One feature of the site will be a blog with and archive view (similar to wordpress etc), this can easily be created on views, but in order to use the i18n menu support, I have resorted to embedding a views block in a node. This works apart from the fact that blocks do not really support pagination without the use of AJAX,
My preference would be to try and use a page 'view' that has support for pagination that can be linked manually from either menu (with support for translation). I would also like to be able to reflect the correct path using the breadcrumbs trail. I am currently using custom breadcrumbs module but this does not seem to support breadcrumb trails when using page views?
In your experience, what do you think will be the best approach to get around these problems? Is this even possible? Your look at menu items seems to have overlooked how to add a page view to the menu with support for translation. I imagine this is probably quite a common problem. Also, I have not seen any mention of support for breadcrumbs using i18n including support for views. I guess this is somehow connected to the menu issue as custom breadcrumbs tends to base the breadcrumb on its menu item path right? By default the breadcrumb trail seems to display the wrong language for some reason. I have also tried to use custom breadcrumbs module to try and overide but without much success. Is there a good resource for this anywhere?
Dan (not verified)
Thu, 01/05/2012 - 18:44
Permalink
views support multilingual
having thought about this - I have worked out that one approach is to add a different page view for each language with it own path.
Simple really, so for each language you simply create a clone of the page and amend the page title, path and filters as necessary!
Gábor Hojtsy
Thu, 01/05/2012 - 20:37
Permalink
i18n page views
http://drupal.org/project/i18_page_views might be of help as well there.
Dan (not verified)
Mon, 01/09/2012 - 16:53
Permalink
excellent
Many Thanks.
With that module I can have a view that acts like a node and the path and breadcrumb change when using the language switcher block. Also avoids having to create clones of page views for each language.
Just what I was looking for.
Shouldn't this be part of the i18n nodule suite aswell?
Gábor Hojtsy
Wed, 01/11/2012 - 12:13
Permalink
consolidation
I agree it would be good to consolidate some modules there. There is already i18n_views as a separate module (not inside the i18n package) that lets you translate views, so maybe it would make sense to put it there.
denjell (not verified)
Fri, 01/20/2012 - 02:06
Permalink
user interaction
I love your series, it gives me hope for drupal8 yet leaves me languishing in the problems of 7. i won't even start about the misery of trying to get civiCRM working in multiple languages. For that you might as well build two sites...
What I am really interested in knowing, however, is best practice for end-user non logged in people that visit the multilingual installation and how they should / could navigate. Drop downs, flags, etc. Any solid solutions other than an ugly link list (even with flags it sucks)?
thanks!
Gábor Hojtsy
Mon, 01/23/2012 - 13:32
Permalink
site specific design
Looks like you are looking for some site specific customizations. For flags, there is the http://drupal.org/project/languageicons module. For making that a dropdown or other kind of better looking widget, it is really not the realm of language support but rather frontend development. That list could just as well be a list of your departments or something else... So I'd suggest you look around for general solutions to making lists into great dropdowns and other things on the web.
Jon McLaughlin (not verified)
Tue, 01/31/2012 - 02:13
Permalink
Shouldn't it be easier?
I have to say, I am a little disappointed now that I understand how things work. I am building a site with 3 languages and it seems like I need to go with option 2 and that means that I will have 3 times the number of menu items in my multilingual menu. They all have to be ordered correctly and kept in their proper parent-child relationships. Since I don't speak the other languages, this makes it difficult to manage.
Unless I'm missing something, option 3, which relies on 'node/%/view' paths, won't allow me to use path aliases. I'm also experiencing Alpha problems with Entity Translation on my in-development site, but that's another issue that I might have to solve for Taxonomy Term field translation.
Why can't the menus work like this.....
Now when the menu is displayed on the /ru site, the menu system could see that the menu item is translated and display "(RU) About Us".. which has a saved path of 'node/1' (the English version of the node) .. At this point, can't it look up the Russian version of node/1 (node/2), from the translation set, and use the path alias of that node instead of showing the path alias of node/1?
So now I would only have one menu item, with multiple translations. Each translation would fetch the right node, and if installed, display the right path alias based on the node's translation set. If the node hasn't been translated to Russian yet, the English version could be shown or maybe the menu item just disappears. If the menu item hasn't been translated to Russian yet, it could show the English version of the item or just disappear.
I'm not versed enough in Core to know if this is feasible, but it seems like it should be. And it seems like it would make things very simple.
This is just me thinking aloud :)
..jon
Gábor Hojtsy
Thu, 02/02/2012 - 12:26
Permalink
agreed
Absolutely agree it is confusing and complicated. Unfortunately core does not support menu item languages neither does it support editing aliases for different languages on the node edit page. So when you edit a node, it will only know of one menu item related and one path related to the node. There are many missing features there. The need for use of node/%nid/view is exactly to overcome the automation in the node/menu system that overwrites your menu items whenever you edit the node.
Yes, the i18n module could be even more invasive and override (or remove) the path alias and menu UI in node forms to avoid this problem. I think that would be a great feature request for the i18n module. I tried to document the options available now and workaround for issues that exist to come to solutions with the tools we have now.
pembeci (not verified)
Tue, 02/07/2012 - 00:37
Permalink
Active menu item
Gábor, first of all thanks for this great series. The path workaround (node/.../view) you proposed for option 3 results in some minor but irritating side effect. When you visit that node by some other means (i.e. clicking the other language version link in the node view page) the path becomes the original one (without the 'view' local task suffix) so the page is not recognized as the active menu item and the relevant css effects (i.e. in bartik that tab is shown as white) are not working. Any suggestions on how to fix this? I checked bartik's page.tpl and I think addition of the 'active' css class happens in theme_links like this:
<?php// ...
if (isset($link['href']) && ($link['href'] == $_GET['q'] || ($link['href'] == '<front>' && drupal_is_front_page()))
&& (empty($link['language']) || $link['language']->language == $language_url->language)) {
$class[] = 'active';
}
// ...
?>
Gábor Hojtsy
Tue, 02/07/2012 - 09:18
Permalink
entity_translation change
I think the ultimate solution would be to kill the path/menu tabs on the node edit form from entity_translation so you don't need to use the path workaround. If the path workaround leads to even more workarounds, then its best to fix the original issue instead IMHO.
Matt (not verified)
Thu, 02/16/2012 - 05:27
Permalink
Cannot reproduce translated menus with Entity Translation
Gábor - thanks for these posts, a real help. I have a question regarding your solution for translated menus used with entity translated nodes. I've spent several hours working and reworking a test environment and cannot get a translated menu item to display. Here's a brief break-down of the set-up, I'd be grateful if you can point to any errors/omissions.
Base Drupal Config
Content Config
Displayed result
I've tried to follow your instructions as closely as possible but am unable to get the menu to switch with the language switcher. Is this perhaps a bug in the release?
Dave Myburgh (not verified)
Mon, 03/26/2012 - 07:01
Permalink
Matt, I see exactly the same
Matt, I see exactly the same thing as you do and have been hitting my head against this for days now. I never had Multilingual Select enabled, but I tried enabling it (node menu items disappeared) and disabling it to see if that kick-started anything...but it didn't. So for now, I'm looking at creating a second menu for the second language. I will then hope furiously that someone will figure this out before I need to add a third language to the site :)
FYI: I've used i18n 1.4, the latest dev version, both with and without the various patches on d.o that supposedly fix this, all with no change.
colan
Mon, 02/20/2012 - 11:16
Permalink
Disable Multilingual Select
See Menu item localizations to ET-translated nodes disappear with Multilingual Select module for details.
Kristen Pol (not verified)
Mon, 03/12/2012 - 22:16
Permalink
Site default language vs. String Translation source language
Hi Gábor,
I think one thing that should be updated/noted is that when *localizing* menu items (and taxonomy terms and custom blocks) is that the Internationalization module will now use the String Translation module's "source language" setting (at Configuration » Regional and language » Multilingual settings » Strings) rather than the site's default language (at Configuration » Regional and language » Languages).
I found this rather confusing until I finally sorted it all out in my head (thanks to Jose) ;) So, my current understanding is that there are 3 default languages:
* English - used for hard-coded strings in module/theme code
* String Translation source language - used for localized user-defined strings handled by i18n module
* site default language - used for sending site emails, setting default user-preferred language and node language, and allowing language to have an empty URL domain/prefix
Hopefully that is all correct!
Cheers,
Kristen
Gábor Hojtsy
Fri, 03/16/2012 - 16:32
Permalink
should be new I think
This should be a new change I think.
Kristen Pol (not verified)
Sat, 03/17/2012 - 02:05
Permalink
Yes, it was added more
Yes, it was added more recently and I don't think it has been fully advertised yet... here's one of Jose's comments from October: http://groups.drupal.org/node/24438#comment-613434
Ufuk (not verified)
Fri, 03/30/2012 - 13:09
Permalink
It is disappointing that
It is disappointing that translation of a menu is so much complicated. A menu is just a set of 5-10 small strings. It could be much simpler in my opinion. Thanks for the clarifying article.
Claude (not verified)
Mon, 04/02/2012 - 17:51
Permalink
Menu translation doesn't seem to be working correctly
I'm having problems getting menu items to translate correctly/at all, and you seem to have the most thorough knowledge (and article) on the web.
- I'm using Drupal 7, with all necessary i18n, multilingual/translation modules etc
- I have a site available in several languages. Base language is EN, which should show on all sites unless a translation is available. I've had to create a module to alter the views SQL to get this to work for showing nodes. I may need to do this for menu items as well, but my initial tests with existing menu translation functionality is failing.
- I have selected "Translate and Localize" for the menu.
What's working:
- I can create a language neutral node, check the box to create a menu link, which appears (the same) on all language sites
- I can create an EN node, check the box to create a menu link, and it appears on the EN site, but not on other language sites.
- I can translate the EN node to FR, check the menu link box again, and the FR menu link appears on the FR site, EN menu link on the EN site. However the default EN menu item wouldn't appear on any other language sites.
What doesn't work:
- If I try to translate the menu item (rather than the node) for an EN node, I can translate it to FR (and the two menu items are linked in the same translation set). The FR menu translation doesn't appear on the FR site. But BOTH the EN and FR menu items appear on the EN menu.
- If I create new menu links in Language Neutral, EN, or FR, all THREE of the links appear on each language site (not just the relevant language)
- If I translate one of these menu links (e.g. select the Language Neutral menu link and create an FR translation), the Language Neutral text still appears on the FR site.
All of this is really confusing, seemingly broken, and even if it did work, may not help me with my specific need to show default/EN content on all language sites unless a translation exists.
Regardless of my specific requirement, any idea of what's going on with menu translations from my descriptions?
ClaudeS (not verified)
Wed, 04/04/2012 - 19:46
Permalink
Since my comment, I've found
Since my comment, I've found out that MegaMenu (in the Marinelli theme) doesn't do any localization. Useful.
I've followed some clues at http://drupal.org/node/1381542 and am now getting some sort of localized data in my menu.
I can also see the difference you described when trying to translate a language neutral menu item (it allows you to localize), versus trying to translate a language-specified menu item (it forces you to create a translation/clone of the menu item for other languages). The latter works correctly when browsing the site in different languages.
However, the former doesn't seem to work.
- My correctly-localized, language-neutral, menu item only shows up in my original/default/neutral language-form. When I visit the site in FR language, I still see the original text, not the localized text. I can confirm in the admin that the FR-localized text is saved fine.
Could this possibly be related to the "i18n_menu_localize_tree" function I'm applying myself to the menu to get it localized?
A minor additional observation: I can create a language neutral menu item, pointed to a node (even if that node is language neutral), but when I save and return to that menu item, it incorrectly tells me that:
- "This menu item belongs to a node, so it will have the same language as the node and cannot be localized."
I presume this is just a wording error, or it's lacking a logic check somewhere, because I can still click translate and localize the single menu item, rather than create translation clones, or define translation sets.
ClaudeS (not verified)
Thu, 04/05/2012 - 18:00
Permalink
Sorry for using your comments
Sorry for using your comments for effectively talking to myself out loud! I was hoping to get some feedback, but have solved the problem myself with some in depth debugging.
It turns out there's a bug in i18n_menu:
http://drupal.org/node/1227812#comment-5832118
Hope this helps anyone else who finds this page and is still having problems getting localization to work. Ensure any menu system you're using has localization code, and that i18n_menu is fixed.
Oren (not verified)
Mon, 04/30/2012 - 17:17
Permalink
first of all - your series is
first of all - your series is pure gold!
I have 8 languages website, and I more or less manage to do all the things you taught in this series, expect one thing.
I have one main menu for all the languages and when I add content in one language, and provide a menu link, i can see in the menu picker all the available parents contents (in all 8 languages), I didn't found any solution for this problem, rather than hacking the core - do you have any kind of salvtion?
I just want the menu dropdown to be fill only with the current language of the content.
caramelmach5 (not verified)
Tue, 05/08/2012 - 19:44
Permalink
Menu translation module?
Hi, you mentioned menu translation module with il8n? I do not have that module, but I do have il8n and translation module. The translate tab does not appear when I try to edit my menus. I am using drupal 7.14
Add new comment