Handling Internal Links in Multilingual Drupal 7 Sites

multilingual hellos

Building a multilingual site in Drupal 7 requires a lot of patience and a lot of special-purpose modules. Checkout my Multilingual Module Madness presentation from DrupalCon Portland if you want to learn more! ;)

There are different ways you can configure a multilingual Drupal site to determine which localized content should be shown to the user on any given page. It can be determined based on the domain, subdomain, path, session, and other settings. One of the most common methods is to use path-prefixed URLs so that if the site is setup for English as the default language and German and Spanish as additional languages then there could be URLs like:

  • http://www.example.com/about-us (English)
  • http://www.example.com/de/about-us (German)
  • http://www.example.com/es/about-us (Spanish)

If sub-domains are used instead, the pages might look like:

  • http://www.example.com/about-us (English)
  • http://de.example.com/about-us (German)
  • http://es.example.com/about-us (Spanish)

And, if domains are used, the pages might look like

  • http://www.example.com/about-us (English)
  • http://www.example.de/about-us (German)
  • http://www.example.es/about-us (Spanish)

This poses a problem when you are adding internal links to content because what URLs do you put into the text? This can be handled in different ways depending on how you are translating your content.

Node Translation

Configuring a multilingual Drupal site to use node translation via the Content Translation (core) module means that there will be one node per language. If the original (source) node is created in English and then translated into Spanish and German, then there will be three nodes for the same content.

Manual Changes

If you are using node translation via the Content Translation (core) module, one method is to just manually change the the link in each translation. For example, the content editor adds text:

<a href="http://www.example.com/about-us">Find out more about us.</a>

and when the node translation for Spanish is created then it's changed to:

<a href="http://www.example.com/es/about-us">Para saber más acerca de nosotros.</a>

This is "simple" but obviously error prone because the content editors or translators need to change all the URLs in the content. This is also a problem if the translations aren't yet available but might be at some point.

Multilink Module

Fortunately, as is often the case in Drupal, there is a module for that (problem). We can use the Multilink modules to make sure that the internal URLs always are pointing to the appropriate translation when available. If we are viewing the Spanish content and linking to an English page, the link will be changed to the Spanish translation of that English page if the translation exists.

Here is the process for using the Multilink module for text areas.

  1. Download multilink with drush or manually

    Multilink Module Download
     
  2. Enable both multilink and multilink_filter modules with drush or via the modules page Multilink Module Enable
     

     

  3. Edit the text filters that you want to use for links and enable the Multilink filter Multilink Module Text Format
     

     

  4. And configure the Multilink filter settings and save the configuration Multilink Module Filter Link Settings
     

     

Now when you edit content and use one of the text formats that you have configured to use Multilink, you will be able to use the source language URL and the links will be changed to the translated node URLs as appropriate. For example, let's assume we have these nodes for our About Us pages:

  • English /about-us => node/227
  • German /de/about-us => node/228
  • Spanish /es/about-us => node/229

Now we create a new English page called "Thank You" with text:

Thank you for your information. We will be contacting you soon. To learn more about our company, <a href="http://www.example.com/node/227">read our about us page</a>.

Multilink Module Thank You Page Filter
 

 

First off, if you don't translate the Thank You page but view the English version of the page in German and Spanish, you will see that it still works as expected.

English page

Multilink Module English Thank You Page
 

 

German page

Multilink Module German Thank You Page
 

 

Spanish Page

Multilink Module Spanish Thank You Page
 

 

And, if we translate the Thank You page into German and Spanish, the Multilink filter continues to work the same way.

Another nice feature of the Multilink filter is that it changes the /node/[nid] URL to use the path alias. For example, /node/227 is changed to /about-us when viewing in English and /de/about-us when viewing in German. In this example, both the English and the German nodes have a path of "about-us" but they can have different paths as well and those would be used instead. If we wanted the German path to be "ueber-uns" then the URL would change to /de/ueber-uns when viewing in German.

Multilink Module German Thank You Page (version 2)
 

 

Using Path Aliases

In the previous examples, the link that was added was the /node/[nid] link. Specifically, the English About Us page was node/227 so the links were hardcoded to "/node/227". Ideally, we are using the node/[nid] paths within content and using filters to fill in the aliases for us since aliases can change. When aliases do change, the Redirect module should be configured to (301) redirect from the old alias to the new one but it is always more efficient to use the most current aliases whenever possible for our internal links.

Sometimes content editors will copy/paste a URL into content, though, and use a URL alias directly. Unfortunately, Multilink doesn't handle the case where the alias is used as the URL like:

Multilink Module Using Alias URL
 

 

So, it is important to give your content editors tools to insert internal links in a way that adds the node/[nid] URLs into the content.

Link Editing Tools

There are several modules that help content editors manage internal links in their content. Note that Multilink does allow you to add links with a special syntax if you know the node id. You can add links like:

[227:read our about us page]

but that doesn't solve the problem of editors not knowing which node to use but Linkit does solve that problem.

  1. Linkit - Best editor UX; will find the /node/[nid] for you
  2. Internal Links - Filter to add title text; Cocomore tutorial
  3. Link Node - For hardcoding in token like: [node:NNN,title="Original version of the picture"]

Here's the interface when using Linkit to search for content:

Linkit UI - Searching

 

Linkit UI - After Selection
 

 

Entity Translation

The previous section covered URLs within node-translated content configured using the core Content Translation module. If you are using the community/contributed Entity Translation module (which you should if you are able to get to work with all your other contributed modules), then you have a slightly different scenario.

With field-translated content, we translate specific fields of a node so we don't get multiple nodes for one "page" but instead have one node per page. For example, if we have a new "More About Us" page, it might have the node id 239.

Fortunately, Multilink also works with Entity Translation as long as you use the /node/[nid] in your URLs just like for nodes handled with Content Translation. Here are examples where another link was added to our Thank You pages that links to field-translated content (the "More About Us" page, node/239).

English Page

Multilink Module English Thank You Page (ET version)
 

 

German Page

Multilink Module German Thank You Page (ET version)
 

 

Spanish Page

Multilink Module Spanish Thank You Page (ET version)
 

 

Node Path vs Aliases

Just like with node-translated content, you need to use the /node/[nid] URLs for internal links within your content and not their path aliases. You can use the same tools discussed above for making this easier for your content editors.

More Free Multilingual Training!

If you are coming to BADCamp (I hope you are!), then you can sign up for our free multilingual Drupal 7 training based on my book: Drupal 7 Multilingual Sites. You get a free book too. You'll need a laptop setup to build Drupal 7 sites. If you are interested in building multilingual sites in Drupal 8 (which is soooo much easier), then checkout the D8 multilingual hands-on lab that we'll be running at BADCamp. Aimee did this lab at DrupalCon Amsterdam with Gábor Hojtsy and it was a great success. Bring your laptop ready for Drupal 8 for this one.

Goodbye! Auf Wiedersehen! Adios!