Version 4 > Developer Guides > Content Model > Translations

Translations

Translations in V4 work on similar principles to those in V3, with some minor changes. The translation relation is more explicitly set via a master column, rather than overloading the parent relation, and the language is more explicitly coded as language, rather than version. There is no special "alternate" type for translated pages. One consequence of these changes is that any content can be translated, not just pages.

v3v4
version

language

alternate

n/a

Language

All content has a language setting, to indicate if the content is in a foreign language. It can be left unset if it is in the default site language (usually English).

The available languages are taken from the dbmap list:language datatype. To add multiple foreign languages, separate their names with the bar character, eg.

Français|Español

As this example shows, it is best to use the native representation of the language name so that it is recognizable to speakers of that language.

Not only the content itself, but also the content title, label, and descriptive metadata should also be in the selected language.

When content has a foreign language setting, the CMS will also try to display auxiliary messages in that language. This includes error messages, button labels, login/logout links, and so on. The translation of those messages is managed by the System Messages module. When a mix of content objects is shown onscreen, the language of the primary content object (usually the page object) determines which language will be used for system messages.

Note that foreign-language pages do not have to be translations; you can simply create pages in other languages and place them into your site map like any other page.

Mirroring

When content is mirrored, every piece of English content has an equivalent content object in the supported foreign language(s). When viewing the site in English, only English content is shown, but when you switch to one of the foreign languages, the foreign content replaces the English content where ever possible. If the site is fully mirrored, that means that no English content is shown, and you only see the alternate language. If the site is partially mirrored, you will see the alternate language where possible, and the CMS will fall back on the English content where no translation is available.

The LanguageMenu plugin can be used to automatically switch between the available languages from any URL that has translations available.

To mirror content, you must set:

  1. the language of the content
  2. the master/original of the content - this points to the English content that this foreign language content replaces

Any mirrored content will return true (1) to the is_translation() call, and the get_translation($language) call will return the equivalent content object in any other supported language.

Mirrored content are distinct content objects from the originals, and must have their own unique names to avoid collisions. Automatically generated names will usually have a 2-character suffix added by default. For instance, if you have a page named contact_us, the auto-generated French translation will be named contact_us_fr. You are free to change that, of course. The translation of a section is often named with just the language abbreviation, so that the translation of 

http://my_website.com

is something like

http://my_website.com/Fr

Mirrored Site Maps

The structure of multilingual content is:

  • master/original content (usually English)
    • translation in language 1 (master field points to English version)
    • translation in language 2 (master field points to English version)
    • etc...

The site map and navigation structure on a mirrored multilingual site always follows the default (English) navigation structure, with the alternate language pages replacing English pages wherever possible.

That means the parent-child relationship of translated content is not used for navigation. It is not ignored, however; it is still used for:

  1. locating the content in the CMS
  2. creating the URL path to the content

That means you can reposition your translated pages for friendlier URLs, or for better organization in the CMS, if you like.

For example, say you have an English page

http://my_website.com/about/contact_us

So the content structure (through the parent relation) is:

  • my_website.com
    •  about
      • contact_us

If you mirror the site in French, the French pages will be placed as close as possible to the position of the English pages, and you will end up with a structure like:

  • my_website.com
    • Fr
    • about 
      • contact_us
      • contact_us_fr
    • about_fr 

Which will result in URLs like:

http://my_website.com/about_fr/contact_us_fr

or, if you rename your French pages:

http://my_website.com/a_propos/contactez_nous

But if you prefer to keep your English and French content organized in different areas in the CMS, or you would like to keep the page names the same so the URLs are are easier to work with, you could reorganize the French content so it all goes under a single subfolder, eg.

  • my_website.com
    • about
      • contact_us
    • Fr
      • about
        • contact_us

Which would produce URLs like

http://my_website.com/Fr/about/contact_us

Translation Management in the CMS

You can manage your translations manually by setting the master and language fields manually.

The Translations module provides a quick way to find, create, and manage your content in translation.

Otherwise, the Modules::Content controller template includes elementary translation management tools that can be borrowed/invoked from any content control panel, as needed.

Translation API

If you need to work with translations in your code, you can make use of the following calls:

Detecting the language status of the current content

$c->is_translation();

returns true (1) if this is translated content; ie. it is in a foreign language and it has a master (English) version. If you just want to detect whether the content is in another language, use:

$c->language();

which returns the language of the content.

Switching to other languages

my $english = $c->master()

returns the original (usually English) content object.

my $fr = $c->get_translation("Français");

returns the respective translation as a different content object.

$c->setup_translation($language);

switches the content object to the translated version.

my %trans = $c->all_translations();

fetches all translations in a hash of language => content object.