multi language website umbraco

14
MenonON.Net – Menon Kalipurayath www.menonon.net Contents Summary of the Multilingual 1:1 site system ......................................................................................... 2 1. Create languages......................................................................................................................... 3 2. Add language tabs to document types ....................................................................................... 4 3. XSLT library function ................................................................................................................... 6 4. Alter all field references .............................................................................................................. 8 5. Use the dictionary with an XSLT extension ................................................................................. 9 6. Replace “hardcoded” text with dictionary calls........................................................................ 12 7. Adding language-selector - You're done! ................................................................................. 13

Upload: sanal-menon

Post on 02-Mar-2015

1.101 views

Category:

Documents


0 download

DESCRIPTION

This book tells you about creating a Multi Language Website in Umbraco?...

TRANSCRIPT

Page 1: Multi Language Website Umbraco

MenonON.Net – Menon Kalipurayath

www.menonon.net

Contents Summary of the Multilingual 1:1 site system ......................................................................................... 2

1. Create languages ......................................................................................................................... 3

2. Add language tabs to document types ....................................................................................... 4

3. XSLT library function ................................................................................................................... 6

4. Alter all field references .............................................................................................................. 8

5. Use the dictionary with an XSLT extension ................................................................................. 9

6. Replace “hardcoded” text with dictionary calls ........................................................................ 12

7. Adding language-selector - You're done! ................................................................................. 13

Page 2: Multi Language Website Umbraco

MenonON.Net – Menon Kalipurayath

www.menonon.net

Summary of the Multilingual 1:1 site system

The idea of the system is to have each document in the Umbraco website contain all localized versions of the document text-fields, and have the code determine which fields to show on the page, depending on the selected language. Thus, there will exist only one copy of each document, each translatable by its own. The site will therefore also have exactly the same information architecture across all languages, hence the label: ”1:1 site system”.

The method described here is equally well-suited for creating new multilingual sites and for adding multi-lingual support to sites that are already created in a single language.

The implementation below assumes that there is an “initial language” – a default as you may. This is typically the language that is chosen when a visitor first enters the site, and also signifies the “master-language” for the web-manager.

The 7 steps for creating the multilingual 1:1 site system are these:

1. The needed languages are first created. Dictionary items can now be added. 2. Each document type will be added a new tab for each language, and new fields for

each localizable field needed, one for each language. The localized fields alias-names are added a postfix consisting of an underscore and the language code.

3. An XSLT library file is created and included in each XSLT file. This file handles language selection, session-storing and retrieval.

4. In every XSLT file, when referring to localizable fields, you will add a concatenation method with the language as parameter.

5. You will now add an XSLT extension that can do lookup in the dictionary using a key and a language id.

6. Replace all that “hardcoded” text that are not contained in document fields, with dictionary entries and a call to the XSLT extension just added.

7. Finally, you should probably add a language selector, so that visitors may choose their preferred language.

The 7 steps are explained in more detail with examples below.

If you don’t need the dictionary functions, you can skip item 5-7, and in that case, you don’t need to write any code in Visual Studio – only XSLT and HTML code.

Page 3: Multi Language Website Umbraco

MenonON.Net – Menon Kalipurayath

www.menonon.net

1. Create languages Define the languages you want to use. (You can easily add more lately) This is done in the

Umbraco client "Settings", under Languages.

You can use the primary languages or languages with variety sub tag as you please (e.g. you

can use English with code en or English (USA) with code en-US. ) Whichever you choose, just

do it everywhere a language-code string is used.

Languages

Example: I have chosen 3 languages without the variety subtag.

Decide which language is the initial language (the “default” as you may.) I choose English in

this case. You may also choose not to have an initial language.

Page 4: Multi Language Website Umbraco

MenonON.Net – Menon Kalipurayath

www.menonon.net

2. Add language tabs to document types On all document types that needs translation (probably all of them, right?), add a new

content tab for each language. If there already is a tab for content, because you are adding

localisation to an existing document type, let this tab contain the translatable fields for the

initial – “master” language. Each tab should be labelled after the language it is to contain.

You can write the full language names here, if you please; no need to use the language-code

(except perhaps for saving screen space).

For each field that needs translation, add the same field to each language tab – but call the

alias for each language that is not the initial language, the field name plus “_” plus the

language-code. Thus, if a text field of type “Textbox Multiple” is called “abstract” on the

initial language tab; make another text field of type “Textbox Multiple” on each language

tab, alias-naming each “abstract_XX” where XX is the language-code.

Take care, that the fields names are exactly the same and placed in the same order. This will

make translations easier for the editors.

Fields that does not need translation (images, links, metadata and so on), you can either

place on the content tab for the initial language, or perhaps even better, move them to a

“common” tab.

Page 5: Multi Language Website Umbraco

MenonON.Net – Menon Kalipurayath

www.menonon.net

Example: An article contains 4 fields, of which only the “author” should not be translated.

The rest are repeated for each tab, adding the language-code postfix to the Danish and

Swedish tabs field aliases.

When the editor creates a new document of the localization-prepared document-type, he

will have a tab for each language, and fields arranged under each tab, with the same names

and order across the tabs.

Example: The article from the example above, as seen in the document editor. The initial

language also contains the “Author” field. Otherwise, the two tabs are identical in

structure and labels.

Page 6: Multi Language Website Umbraco

MenonON.Net – Menon Kalipurayath

www.menonon.net

3. XSLT library function Add an XLST file to the “Developer” section of your Umbraco project. You can call it

lang_lib.xslt or another name of your choice. Below is a complete sample of the code that

needs to be included:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet

version="1.0"

xmlns:xsl=http://www.w3.org/1999/XSL/Transform

xmlns:msxml="urn:schemas-microsoft-com:xslt"

xmlns:umbraco.library="urn:umbraco.library"

xmlns:kv_trans ="urn:kv_trans"

exclude-result-prefixes="msxml umbraco.library kv_trans">

<xsl:output method="xml" omit-xml-declaration="yes"/>

<xsl:param name="initlang">en</xsl:param>

<xsl:variable name="dlang">

<xsl:choose>

<xsl:when test="umbraco.library:RequestQueryString('lang') != '' ">

<xsl:value-of select="umbraco.library:RequestQueryString('lang')" />

</xsl:when>

<xsl:when test="umbraco.library:Session('lang') != ''">

<xsl:value-of select="umbraco.library:Session('lang')" />

</xsl:when>

<xsl:otherwise>

<xsl:value-of select="$initlang" />

</xsl:otherwise>

</xsl:choose>

</xsl:variable>

<xsl:variable name="flang">

Page 7: Multi Language Website Umbraco

MenonON.Net – Menon Kalipurayath

www.menonon.net

<xsl:if test="$dlang != '' and $dlang != $initlang ">

<xsl:value-of select="concat('_',$dlang)" />

</xsl:if>

</xsl:variable>

<xsl:template name="setlang">

<xsl:value-of select="umbraco.library:setSession('lang',$dlang) " />

</xsl:template>

</xsl:stylesheet>

Reference to this XSLT file is to be included on all pages that need translation.

What does it do?

A variable, $dlang, is assigned the resolved language code. This variable can be used for

dictionary lookups, hence the “d”. Resolving the language code is done by checking the

query string and the session for a defined language. Note that the query string has priority,

so that changing the language is as simple as passing a new query parameter.

If the language is not found, it uses the initial language “initlang” defined at the top of the

stylesheet. You can here change “en” to a default language-code that fits your needs.

Another variable - $flang – is also set, but only if it’s not the initial language. The $flang is

created by concatenating an underscore and the $dlang, and is used for localized field-value

fetches – hence the “f”. (More on this later)

Finally, a named template method “setlang” is defined. This method should be called at the

top of all pages that contains the option of language-selection – in practise all pages. To

make sure it’s called for all pages, and only once, place the call in an XSLT used in one of the

top-most master templates. The call is simply done with a “call-template” element like this:

<xsl:template match="/">

<xsl:call-template name="setlang" />

</xsl:template>

Obviously, the library file must also be included in the XSLT file for the call to work. (See

below.)

Page 8: Multi Language Website Umbraco

MenonON.Net – Menon Kalipurayath

www.menonon.net

4. Alter all field references Now we need to alter the XSLT files to look for the correct field from the displayed

document.

First make sure to include the lang_lib.xslt (from step 3) in the beginning of all XSLT files that

need translations. You should add it between the Stylesheet element and the first template

element.

<xsl:include href="../xslt/lang_lib.xslt" />

You need to substitute each reference to a field with the X-path concat function, adding the

languagecode defined in lang_lib.xslt. Example: Say, the alias name of a field is:

“ALIASNAME”, we might have this code:

<xsl:value-of select="$currentPage/data[@alias = 'ALIASNAME']" />

We need to change it to this:

<xsl:value-of select="$currentPage/data[@alias = concat('ALIASNAME',$flang)]" />

The concat function combines the fieldname with the language postfix, exactly as we have

created the localized field-alias names in the document type in step 2. Thus the <xsl:value-of

... selects the correct translation and uses that. If we use an initial language, the value of

$flang is the empty string and the concat method will have no effect, returning the field

name without the language postfix, and thus referring to the field value from the “default”

content tab - the "initial language".

Page 9: Multi Language Website Umbraco

MenonON.Net – Menon Kalipurayath

www.menonon.net

5. Use the dictionary with an XSLT extension When you create entries in the dictionary, you do as normally in Umbraco – create the entry

using the key and adding a translation for each language.

In this example, the website title is a dictionary item, using the key “sitetitle”.

To refer to this key, we want to simply use a library function to look up by key and language.

Unfortunately, the current umbraco:library does not support that, so lets just make our own

extension and add this support.

Create a Visual Studio project - Class library - and include a reference to the umbraco.dll file.

Create a class to hold the translation code. You could call it “Translations”. Create a public

method that will be the method you invoke from the XSLT files. Call it “translate”. My

implementation looks like this:

using System;

using System.Collections.Generic;

using System.Text;

using System.Xml;

using System.Web;

using System.Xml.XPath;

using umbraco.cms.businesslogic;

using umbraco.cms.businesslogic.language;

// Adds dictionary lookup as an extension for XSLT files. /TORK 2008.04.30

Page 10: Multi Language Website Umbraco

MenonON.Net – Menon Kalipurayath

www.menonon.net

namespace kraftvaerk.umbraco

{

public class Translations

{

/// <summary>

/// Look up a translated string in the Umbraco dictionary using the provided key and

language code

/// Returns the translated string if found and not empty. Else, it returns the key and the

language

/// surrounded with "*" for easy detection and correction.

/// </summary>

/// <param name="key">The key by which the dictionary entry was made</param>

/// <param name="language">The desired language code- as it appears on the dictionary

tabs</param>

/// <returns>The translated string, if found and not empty. returns>

public static string translate(string key, String language)

{

int langid = 1;

if (language.Length != 2) language = "en"; // hardcoded default language.

Reimplement as desired.

Language lang = Language.GetByCultureCode(language);

langid = lang.id;

string trans = GetDictItemByLang(key, langid);

if (trans.Length > 0) return trans;

return ("*" + key + "(" + language + ")" + "*");

}

/// <summary>

/// Lookup the key in the Dictionary, then get the value for the correct language-id

/// </summary>

Page 11: Multi Language Website Umbraco

MenonON.Net – Menon Kalipurayath

www.menonon.net

/// <param name="key">The key by which the dictionary entry was made</param>

/// <param name="languageid">The id of the choosen language</param>

/// <returns>The translated string or the empty string. returns>

private static string GetDictItemByLang(string key, int languageid)

{

try { return new Dictionary.DictionaryItem(key).Value(languageid); }

catch { return string.Empty; }

}

}

}

Please change the namespace :-)

Add the extension declaration to the \config\xsltExtensions.config file.

If you have no other extensions registered, it should look something like this, when you’re

done:

<?xml version="1.0" encoding="utf-8" ?>

<XsltExtensions>

<ext assembly="/bin/kv_umb_lib" type="kraftvaerk.umbraco.Translations"

alias="kv_trans" />

</XsltExtensions>

Change the assembly name, the namespace and the alias as appropriate to your needs.

Page 12: Multi Language Website Umbraco

MenonON.Net – Menon Kalipurayath

www.menonon.net

6. Replace “hardcoded” text with dictionary calls Now, we can add this extension in all XSLT files where we need dictionary translations.

First we need to add the namespace declaration in the stylesheet element:

<xsl:stylesheet

version="1.0"

xmlns:xsl=http://www.w3.org/1999/XSL/Transform

xmlns:msxml="urn:schemas-microsoft-com:xslt"

xmlns:umbraco.library="urn:umbraco.library"

xmlns:kv_trans ="urn:kv_trans"

exclude-result-prefixes="msxml umbraco.library kv_trans">

...

(The added code is highlighted.)

Then we can use it this way anywhere in our XSLT file:

<xsl:value-of select="kv_trans:translate('KEY',string($dlang))" />

Where the ‘KEY’ is the dictionary key for the entry, as explained in step 5.

Again, change the namespace and alias name to what you used above, in step 5.

Page 13: Multi Language Website Umbraco

MenonON.Net – Menon Kalipurayath

www.menonon.net

7. Adding language-selector - You're done! All we need now is a language selector. To implement it, we just need a link to the same

page. To the Href attribute of this anchor-tag (that is the language selector), we add the

querystring: “?lang=XX” where XX is the language code to switch to.

In my example, I use this HTML code in the page-header XSLT-file:

<div class="languageselector">

<a href="?lang=en">ENGLISH</a>&nbsp; | &nbsp;

<a href="?lang=sv">SVENSKA</a>&nbsp; | &nbsp;

<a href="?lang=da">DANSK</a>

</div>

Example: Here we see the result. The mouse is hovering over the “DANSK” link – that

switches the site into Danish. Notice the link URL at the bottom. ?lang=da is all it takes to

switch.

That’s it!

Page 14: Multi Language Website Umbraco

MenonON.Net – Menon Kalipurayath

www.menonon.net

Translating the site one-to-one and using dictionary items.