Multi Lingual Websites In Umbraco


Published on

Presentation given at UK Umbraco User Group Meeting in Summer 09

  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Personal introduction…Orcare is an IT Services company, we specialise in supporting growing businesses and charities. But the fact is that for most small businesses their website is their greatest IT investment. When developing websites we’ve used Umbraco exclusively for just over a year.…Orcare has been a full time job for me since July 2009, before then I was Project Manager Technology Introduction for British Airways where I specialised in the evaluation and introduction of enabling and cost reduction technologies, like Oracle Real Application Clusters, Red Hat Linux and SOA tools such as iLogJrules and Sonic ESB.
  • Collaboration between Red Box Media and Orcare…This is a story of compromise with may offend the architectural sensibilities of many of you present. We compromised in some cases because we needed to maintain backwards compatibility. But more often than not we compromised because of my naivety.…When we started this was only my 3rdumbraco website, and the two that came before were simple 10 page brochure site.…If I had my time again there are a couple of significant changes I would have made to the way we built the site. But I’ll explain those as I go along.
  • This is a snapshot of the Russian home page. The design is entirely the work of Red Box Media.
  • When the project started they were an independent private company. But they have since been taken over by Aecom a US based Fortune 500 construction management company.…Fairly standard corporate brochure site.…For example there is a micro-site for Latvia that is in English and Latvian and Kazakhstan micro-site in English and Kazakh
  • Not a huge site but it was my biggest to date
  • In the 1:1 pattern your build document types in your site such that they contain a complete set of properties for each language. For example, if you have a TextPage document type with a Title and BodyText property, you would need a TitleLang1 and TitleLang2 and BodyTextLang1 and BodyTextLang2. This structure is fairly rigid (implied in the name) because it requires all content to be in all languages, which isn’t the case in many sites, and if you have multiple languages you need to replicate fields for all languages. This pattern also breaks certain Umbraco freebies such as the dictionary (more on this later). But it’s fairly easy to setup and get your head around, and in some cases editors will prefer the ease of navigation (again more on this later).The alternative approach is to create multiple branches in the site, one for each language. Translated copy can then be related together so that you can link nodes in your macros. This has the advantage of flexibility – you don’t have to use the same site structure or content in different languages, and a google search of the forum places a lot of weight behind this approach. It’s a little trickier to setup but not rocket science. But crucially we found that it can also make managing the site harder for editors.
  • Multi Lingual Websites In Umbraco

    1. 1. Multi-lingual Websites in Umbraco<br />A Case Study of<br />Paul Marden<br />Director<br />
    2. 2. Background<br />This is a practical case study, not intended to be a demonstration of best practice.<br />Project was to migrate an existing ASP / Flash site from a proprietary CMS to Umbraco.<br />Aim was to provide a functionally equivalent front-end that required the minimum amount of rework of the Flash components.<br />
    3. 3.
    4. 4. About the client<br />Savant is an international construction company with 20 offices across 13 countries in Europe and Central Asia.<br />Their site provides all primary content in English and Russian, with 11 regional office micro-sites in English and that country’s language.<br />In all cases there is a 1-to-1 match between English / Russian nodes or English / 3rd Language nodes.<br />
    5. 5. Specs<br />Built on 4.0.0 RC1 and currently deployed on 4.0.1<br />Running on Fasthosts dedicated server;<br />Windows Server 2003 Web Edition<br />SQL Server 2005 Express Edition<br />~320 nodes, 22 document types, 28 templates & 23 macros<br />
    6. 6. Flash integration<br />The site uses Flash movies extensively to display content in an attractive way.<br />Much is legacy code inherited from the existing version of the site/cms.<br />We made use of sIFR v3 to render page headers and menu’s.<br />Started with fonts generated by sIFR Generator but reverted to creating the sIFR font file in Flash – not all Cyrillic fonts are the same!<br />
    7. 7. Approaches to multilingual sites<br />After some research there seemed to be two design patterns for multi-lingual sites:<br />Multi-lingual 1:1 sites (as written about by Torleik)<br />Separate branches for each language<br />We ended up with a compromise between both!<br />
    8. 8. Separate host names<br />Originally designed to separate out English and Russian pages with two root nodes. In the dev version these had separate host names and languages (best practice?).<br />Also required configuration of IIS to route traffic to the appropriate Website!<br />An advantage of this was that we could have Cyrillic URL’s giving better SEO.<br />
    9. 9. Information Architecture<br />
    10. 10.
    11. 11.
    12. 12.
    13. 13. But...<br />Existing Flash movies for News, Projects etc, needed EN & RS in the same XML feed, so we needed a way of retrieving EN & RS for News Item 1, News Item 2 etc.<br />URLs with Cyrillic&apos;s broke the movies and rendered rather strangely when pasted into emails...<br /><br />We kept the separate root nodes for EN and RS, but gave up on Cyrillic URLs and also didn’t implement separate host names. Instead naming pages e.g. Experience.aspx and ExperienceRS.aspx<br />! This was a bad design decision !<br />
    14. 14. Relating nodes<br />Each page on the site has to relate together EN and RS content, so that it was possible to flick between different language versions of the page.<br />We achieved this using a content picker field on each doc type.<br />Within the template we call a macro to insert the link to the other page:<br />&lt;xsl:variable name=“link” select=“$currentPage/data[@alias=&apos;LinkedPage‘]”/&gt;<br />&lt;xsl:if select=“$link != ‘’&quot;&gt;<br /> &lt;a href=&quot;{umbraco.library:NiceUrl($link)}&quot;&gt;English&lt;/a&gt;<br />&lt;/xsl:if&gt;<br />
    15. 15.
    16. 16.
    17. 17. Listing pages<br />The site consists of four “database” like document types. These hold job opportunities, projects completed, press releases and office locations.<br />Each is output on a listing page. This page contains a paged static HTML version of the items, as well as a call to a Flash movie which retrieves the items as an XML file to display a prettier version.<br />We began with separating out the list item nodes by language, but the users found this difficult to manage, so we reverted to a 1:1 multilingual pattern.<br />
    18. 18.
    19. 19.
    20. 20. Listing pages (templates & macros)<br />Each listing has an HTML view and an XML view.<br />In order to retain backwards compatibility with existing Flash movie we implemented two pages e.g. news.aspx and getNewsXML.aspx. Each had their own Document Type, Template and Macro for retrieving list items.<br />Although were it to be a virgin site, I would have gone for one page, with two templates then used ?alttemplate=othertemplate<br />
    21. 21. Plan was deploy to Savant’s shared server architecture.<br />But once deployed we found this was a medium trust environment.<br />So the day before planned go live we bought a Fasthosts dedicated server.<br />Implementation Pains<br />
    22. 22. Dictionary<br />In the latest edition of the site we’ve implemented translation using the Umbraco dictionary.<br />This makes use of the Languages defined for the site to display a neat interface (in U4) that display words to be translated.<br />Functions are then available in umbraco.library to insert a translated value for a certain keyword.<br />This reduces the number of macros in the site, simplifies them, and provides a better editors interface.<br />
    23. 23.
    24. 24. Standard dictionary access <br />In a macro to retrieve a translated value use:<br />&lt;xsl:value-of select=“umbraco.library:GetDictionaryItem(‘Aviation’)”/&gt;<br /> Which returns a string containing the translated value using the current language context.<br /><ul><li>Language context is calculated by the hostname.</li></li></ul><li>Orcare Dictionary Access (part 1)<br />Reading the API docs (with help from Ron Brouwer) I found that it is possible to access the Dictionary via the API.<br />Attempt number 1 tried to embed a C# function into the macro’s XSL. Plagiarising code from Doug’s XSLTSearch.<br />But I couldn’t make the call out to the api...<br />
    25. 25. Orcare Dictionary Access (part 1)<br />&lt;msxsl:script language=&quot;C#&quot; implements-prefix=&quot;orcare&quot;&gt;    &lt;![CDATA[    public string GetDictionaryItemByContext(string key, intlanguageId)    {        return new umbraco.cms.businesslogic.Dictionary.DictionaryItem(key).Value(languageId);    }    ]]&gt;&lt;/msxsl:script&gt;<br />Error in XSLT at line 233, char 20231:       public string GetDictionaryItemByContext(string key, intlanguageId)232:       {233: &gt;&gt;&gt;   return new umbraco.cms.businesslogic.Dictionary.DictionaryItem(key).Value(languageId); &lt;&lt;&lt;234:       } <br />
    26. 26. Swag Alert<br />
    27. 27. Orcare Dictionary Access (part 2)<br />So we built our own library which can be called from XSL files.<br />Based on very old notes from Wikibooks.<br />Create a new project<br />Create a class (OrcareLib)<br />Import all the necessary parts of the Umbraco API<br />Create your methods<br />
    28. 28. Public Class OrcareLib<br /> Public Shared Function GetDictionaryItemByLanguageId(ByVal key As String, ByVallanguageId As Integer) As String<br /> Dim d As New Dictionary.DictionaryItem(key)<br />GetDictionaryItemByLanguageId = d.Value(languageId)<br /> End Function<br /> Public Shared Function GetDictionaryItemByCultureCode(ByVal key As String, ByValcultureCode As String) As String<br /> Dim d As New Dictionary.DictionaryItem(key)<br /> Dim l As Language<br /> l = Language.GetByCultureCode(cultureCode)<br />GetDictionaryItemByCultureCode = d.Value(<br /> End Function<br />End Class<br />Orcare Dictionary Access (part 2)<br />
    29. 29. Build the project, and copy the dll into the /bin folder in umbraco<br />Register the library in /config/xsltExtensions.xml<br />&lt;ext assembly=&quot;/bin/OrcareLib&quot; type=&quot;com.orcare.OrcareLib&quot; alias=&quot;orcare.library&quot; /&gt;<br />Add the library into the head of any XSL files<br />xmlns:orcare.library =&quot;urn:orcare.library&quot; exclude-result-prefixes=&quot;msxmlumbraco.libraryorcare.library”<br />Call the new methods<br />&lt;xsl:value-of select=“orcare.library:GetDictionaryItemByCultureCode (‘Aviation’,’ru-ru’)”/&gt;<br />Orcare Dictionary Access (part 2)<br />
    30. 30. Think more carefully about how you architect the site.<br />1:1 may be easier for your users, but breaks the dictionary.<br />Separate hostnames for separate languages gives much better flexibility, but can be confusing for editors.<br />But the editors still love the editing experience in Umbraco, even with the compromises we made.<br />If you are planning to deploy to a new environment test it early to make sure it’s suitable.<br />Parting shots<br />