Content Translation on a Drupal 7 Site
Recently, I had the pleasure of implementing the ability to translate content on a Drupal 7 site. Here is an outline of my recent experiences that will hopefully help any developer who is having trouble getting started with content translation in Drupal 7.
Our client’s requirements were as follows:
- Create two “site regions” (languages): North America and Europe
- Provide the ability to translate a node for each region
- Automatically detect location of user by IP address and redirect them to either the North American or European translated site based on a mapped list of countries
In this post, I address client requirements #1 and #2 listed above, with details on #3 coming in a subsequent post down the road.
Step 1: Create Two Predefined Regions—North America and Europe
In the configuration of the “Locale” module (/admin/config/regional/language), I was able to change the default name of the “English” language to “North America” as well as add an “English, British” language that I renamed to “Europe.”
Part of the client’s requirements were that the language be determined via a path prefix (e.g., http://example.com/en/, or http://example.com/en-gb/), accomplished by selecting the “Determine the language from the URL (Path prefix or domain)” check box in the “Detection and Selection” tab of the “Locale” configuration page.
Step 2: Content Translation
After reading, Drupal 7′s new multilingual systems compilation, I was certain the Content Translation module (d7 core) was all that was needed to serve region- (language) specific content. After enabling and configuring the “Content Translation” module as well as editing the “Multilingual” support section of my content types so that they were translatable, it appeared that everything was working as desired. I was now able to create a node, assign a node to a particular language and create the corresponding translation.
To test the translations, I enabled the “Language Switcher” block that is automatically created by the “Content Translation” module. Now while viewing a node, located at http://example.com/my-node, if I clicked “Europe” on the “Language Switcher” block, the URL changed to http://example.com/en-gb/my-node and the Europe translation is displayed. WINNING, right?! Just as I was ready to mark my Bugzilla ticket as completed, I realized a show stopper. Menus…
Since “Content Translation” actually creates an entirely new node for each translation, there was no way for me to have one menu item that would link to the corresponding node translation depending on which region is selected. The test node I created previously had a menu item titled “My Node,” assigned to the North America language translation, and I gave both translations the same exact path alias—my-node—assuming the Drupal menu system would be smart enough to handle the node translations, but the results were not as I desired.
When on a page in my Drupal site without a language path prefix (e.g., http://example.com, and I click my menu item, “My Node”), I am taken to the nodes page, http://example.com/my-node. Now when I click the Europe link in my “Language Switcher” block, I am taken to http://example.com/en-gb/my-node. Here was my issue—now when I click on my “My Node” menu item, it takes me to http://example.com/en-gb/node/1 (1 being the node ID of my North American translation). I was expecting to be taken to the same page I was currently on, or at the least taken to the North America translation for the node using the correct path: http://example.com/my-node.
Up until now, I had been fairly calm and the process had been, for lack of a better word, painless. But the pain had just started. I began to research/search/scour the web in hopes of finding a similar situation and solution. Unfortunately, the only “solution” I found was to use the “i18n Menu Translation” module, which essentially requires you to duplicate EVERY menu item, child-item, etc… Now, I’m furious. Really, Drupal? While going the “Menu Translation” route may work for a site with a simple one-level main menu, the menu in this project was about three levels deep, not to mention that on some of the Panel pages, we were displaying menu segments that were path specific. Just as I was about to throw my hands in the air and surrender/purchase Joomla stock/apply for a job at In-N-Out Burger, I stumbled across a magical module called Entity Translation!
Entity Translation FTW!
The difference between the “Entity Translation” module and d7′s core “Content Translation” module is that the former does NOT create additional nodes for translations, it translates on a field-able entity level. Now, this made much more sense to me. I would have one node with translated fields as opposed to two separate nodes with the “Content Translation” module.
It was during this process that I also discovered the “Path Translation” module, part of the i18n collection.
Winning Combo: Entity Translation + i18n Path Translation
After countless hours, I had finally found my winning solution. With both the “Entity Translation” and “i18n Path Translation” modules enabled, I changed the “Multilingual” support section of my content type to “Enabled with field translation.” I cleared my Drupal cache, refresh, and… boom! A single menu item per node regardless of how many translations it has. Translated content is displayed based on the URL’s path prefix, and correct path aliases are used. Success, I can mark my Bugzilla ticket as completed, sell my Joomla stock and politely decline my employment offer from In-N-Out!
While I am no expert on creating Multilingual Drupal 7 sites, I don’t understand why/when one would use “Content Translation” over “Entity Translation.” The whole concept of translating on an entity level rather than a node level just made more sense to me. I cannot see any benefit of creating an entirely new node just for a translation.
I hope somebody finds this post useful as I wish it existed when I first started on this task. For more on our thoughts about Drupal, check out our Drupal page.