Multilingual websites in Umbraco 8
Heads Up!
This article is several years old now, and much has happened since then, so please keep that in mind while reading it.
My multilingual website adventures began back in 2015 whilst I was studying a master’s degree in IT at Loughborough University. I sat a module called ‘International Computing’ which at the time I didn’t really appreciate, however it taught me many important things about making software suitable for a global audience, like supporting character sets, localisation, internationalised domain names and setting up databases with the right encodings. So, when the opportunity to put my newly gained knowledge into practice, I jumped at it!
The first multilingual Umbraco website I built was on version 7, at the time it was huge improvement over the PHP based multilingual website I built for the ‘International Computing’ module, however I still felt like the process of building and editing the website could have been easier.
Fast forward to working at Cogent and I am currently working on a multilingual website for one of our clients which could eventually be translated in up to 7 languages. It is also the first Umbraco 8 website that we have worked on.
Until now we have been holding off moving to Umbraco 8 for multiple reasons:
- Umbraco 8 is new, and we wanted to give it a few months for major bugs, if any, to be patched.
- The documentation is still limited compared to the wealth of information there currently is for Umbraco 7. We wanted to wait for it to be a bit more documented, so it is easier for us to transition.
- Umbraco 8 will require us to rewrite a lot of code for functionality we have written previously for Umbraco 7, so we wanted to start with a project this is going to benefit a lot from using Umbraco 8 over Umbraco 7.
News that the translation features had been improved in Umbraco 8 made this project a good candidate to be our first website on this version.
One of the first things I did was quickly throw together an Umbraco 8 installation just to see what using Umbraco 8 involves and how the translation functionality works. It didn’t take me long to realise that there are many improvements over v7.
There only needs to be one node tree for all the languages
Adding new content to the Umbraco 7 website was a time consuming task, each language had it's own separate node tree, and each time a page was added to the website I had to add it to each of these node trees. This wasn't so bad with the three languages that the website initially started with, but if more were to be added at a later date it would become a much more time consuming task for the content editor. Even with just three languages, adding content felt a bit monotonous particularly when adding content that is the same across each languages like images.
I could have worked around this by adding a ‘tab’ for each language on the page but this would have required a lot of repeated properties in the doctypes, and each time a language was added to the website I would have to manually add more properties to the doctypes. This method would also require a lot of work to get the page URLs to display correctly for each language, as the slug would have been in the default language.
In Umbraco 8 only one node needs to be created for a page that is translated into multiple languages, within this node I can switch between languages and edit content, and upon publishing it asks which of the languages I want to publish. If I were to add another language to the website I don't have to create any new nodes or doctypes, I just add the language to the culture settings and it creates a new language variant based on the content I already have there, I just have to add the translation and publish. Umbraco also automatically creates all the translated URL slugs when each of the languages is published.
Easier navigation and editing
Umbraco 8 is overall a better editing experience generally, but there are a few things specifically that work well for multilingual websites. Allowing the nodes to have varying languages allows a relationship between the content of different languages.
In Umbraco 7, for example, the 'contact us' page for each language would have been a completely separate page, with no relation to the 'contact us' pages of other languages. This can make the editing experience difficult because if you had to remove the 'contact us' page for each language, you would have to first know what 'contact us' is in each of the languages (hello Google Translate!), and then manually delete them all.
In Umbraco 8 I can use the dropdown to switch the content to English, find the page I want to remove and delete it across all languages in one go. Or if it only needs to be removed from one language, just un-publish the node for that language. Easy!
I can edit the content of two languages side by side
A person writing the content for the website can see the content in one language whilst they are writing the content for another. This was only possible in Umbraco 7 if two browser tabs were open side by side.
I can choose which properties and doctypes can be translated
To allow a doctype to be translated into multiple language variants I simply check a box under the permissions for ‘Allow varying by culture’ and then for each property in the doctype I enable this also.
You might be thinking, ‘which nodes don’t have to be translated? Surely you want all the content to be translated?’ I have some nodes in the website which I use for configuration that will be global to all the translated variants of the site, it would be unnecessary to ‘translate’ these properties because they are the same across all the languages.
Conclusion
Overall, I have found the Umbraco 8 translation experience so much easier than 7. Umbraco 7 didn’t feel as if it was built for multilingual websites, it was like I was squashing multiple separate websites into one installation rather than having a single translated website. Umbraco 8 allows a fluid editing experience from one language to another.
Code Snippets
If you are thinking of translating an Umbraco website I have a few code snippets that may help you:
String Replace variables in the Dictionary
Sometimes variables are added into text like below:
Showing @startNum - @endNum of @totalNum Products
This could be translated by the Umbraco dictionary by adding 3 separate words in there “Showing”, “of” and “Products” which would produce the following code:
@umbHelper.GetDictionaryValue(“Showing”) @startNum -
@endNum @umbHelper.GetDictionaryValue(“of”)
@totalNum @umbHelper.GetDictionaryValue(“Products”)
There are a few issues with this:
- It may not be obvious in the translate section the context of these three words, which may lead to them being incorrectly translated.
- The sentence structure (and therefore order of the variables) may change when translated into another language. This cannot be fixed by the translator.
I solved these issues by doing a simple string replace on the variables in the sentence.
<div class="item-count">
@umbHelper.GetDictionaryValue("Showing {startNum}-{endNum} of {totalNum} Products")
.Replace("{startNum}", startNum.ToString())
.Replace("{endNum}", endNum.ToString())
.Replace("{totalNum}", productCount.ToString())
</div>
This allows translators to see the context of what they are translating in Umbraco, and if they need to can alter the order of the variables.
Localising DateTime properties
Date formatting can vary from region to region. Umbraco makes it very easy to change the formatting of any dates with the following code:
Long date:
@Model.Content.CreateDate.ToString("D")
Short Date:
@Model.Content.CreateDate.ToString("d")
Here is a table of examples that this code prints out:
|
En-gb |
En-us |
fr |
Short Datetime |
01/10/2019 |
10/1/2019 |
01/10/2019 |
Long Datetime |
01 October 2019 |
Tuesday, October 1, 2019 |
mardi 1 octobre 2019 |
Apparently, the British don’t care for the day of the week…
I created a new method to correct this:
public static string ConvertDateTimeLong(this DateTime date, string culture)
{
CultureInfo location = new CultureInfo(culture);
string format = location.DateTimeFormat.LongDatePattern;
switch (culture.ToLower())
{
case "en-gb":
return date.ToString("dddd "+format);
default:
return date.ToString(format);
}
}
Further links:
https://our.umbraco.com/documentation/Getting-Started/Backoffice/Variants/
Harriet Lawrie
Harriet is on Twitter as @Harriet_Lawrie