Many tutorials may be found when coming to localize a website. However the best I found is undoubtedly the document written by the creator of TYPO3, namely Kasper Skårhøj:
Anyway, here is a brief summary of what should be done…
Beware if you use TemplaVoilà: make sure extension static_info_tables is loaded, otherwise you won’t see any translation tab in module Web > Page.
TYPO3 store the default language content with sys_language_uid = 0. The default language in itself is fully arbitrary but it’s a bit more user-friendly to define its name and flag in the backend. This is done in the pageTS of the root page of your site:
# Default language mod.SHARED { defaultLanguageFlag = gb.gif defaultLanguageLabel = English } # Translation must be bound 1-1 to the default content mod.web_layout.defLangBinding = 1
In order to properly render content to frontend, following TypoScript code should be placed in your template. I assume here that the website is using UTF-8 encoding:
# English as default language config { sys_language_uid = 0 language = en locale_all = en_GB } page { config.htmlTag_langKey = en meta.language = en }
There is something worth being aware of in previous code. Value of locale_all is related to locales installed on your server.
Use following commande, with Linux, to get the list of available locales:
# locale -a
C
de_CH.utf8
en_US.utf8
fr_CH
fr_CH.iso88591
fr_CH.utf8
POSIX
You want another locale? Simply edit file /etc/locale.gen:
en_US.UTF-8 UTF-8
fr_CH.UTF-8 UTF-8
de_CH.UTF-8 UTF-8
fr_CH ISO-8859-1
and execute following command to actually regenerate them:
# locale-gen
Generating locales (this might take a while)…
en_US.UTF-8… done
fr_CH.UTF-8… done
de_CH.UTF-8… done
fr_CH.ISO-8859-1… done
Generation complete.
If you wish to translate your website, you just have to create as many as additional languages as you want using Web > List and by adding records of type sys_language. Keep a track from generated id, they will be useful to map language to sys_language_uid in Frontend.
[globalVar = GP:L=1] config { sys_language_uid = 1 language = de locale_all = de_CH.utf8 } page { config.htmlTag_langKey = de meta.language = de } [globalVar = GP:L=2] config { sys_language_uid = 2 language = fr locale_all = fr_CH.utf8 } page { config.htmlTag_langKey = fr meta.language = fr } ... [global] config.linkVars = L # Best practice config.sys_language_mode = content_fallback # Translation must be bound 1-1 to the default content config.sys_language_overlay = 1
lib.links.languages = HMENU lib.links.languages { special = language special.value = 1,0,2,3 special.normalWhenNoLanguage = 0 1 = TMENU 1 { noBlur = 1 NO = 1 NO { allWrap = <li>|</li> stdWrap.setCurrent = DE || EN || FR || IT stdWrap.current = 1 ATagTitle ( Diese Seite auf Deutsch zeigen || Show this page in English || Afficher cette page en français || Visualizza questa pagina in italiano ) ATagParams ( lang="de" xml:lang="de" || lang="en" xml:lang="en" || lang="fr" xml:lang="fr" || lang="it" xml:lang="it" ) } ACT < .NO ACT { stdWrap.setCurrent ( <span class="current">DE</span> || <span class="current">EN</span> || <span class="current">FR</span> || <span class="current">IT</span> ) doNotLinkIt = 1 } # Non-translated pages should be "active" anyway USERDEF2 < .ACT } }
Interesting Links
If you wish to be able to translate and localize fields of a flexible content element, you have to modify its XML structure (at the beginning of the definition):
<T3DataStructure> <meta type="array"><langChildren>1</langChildren><langDisable>0</langDisable></meta>
From now on, whenever you edit such a content block, you will be able to translate its field contents. Would a field be left empty, the master content would be automatically used instead:

