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.
Exploiting block visibility for menu languages
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.
Connect items of different menus as translations
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.
Keeping menu items together with localizable menu items
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.
The entity translation connection
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!