1-1 Multilingual websites with Vorto and Nested Content
Heads Up!
This article is several years old now, and much has happened since then, so please keep that in mind while reading it.
Vorto
Vorto is a property editor wrapper and converts it into a multilingual property by allowing you to enter multiple values per language enabled on the site. With this package alone you're already able to create great 1-1 translations.
Nested Content
With Nested Content you can make repeatable fieldsets. These are based on document types and are even returned as an IPublishedContent in the code. However we don't need the repeatable part, but Nested Content also supports a single fieldset.
Nested Content document type
For this example I've downloaded the Txt Starter Kit and will make the News Item multilingual. The date and image don't have to change per language so we'll only make the subheader and text multilingual. For Nested Content I've created a document type called NewsDetached with the subheader and text property. I always put document types used for Nested Content in a separate folder called Detached because internal Nested Content works with a class called DetachedPublishedContent.
Nested Content data type
The Nested Content data type uses the NewsDetached document type. If we wouldn't change anything else this would be repeatable, but Nested Content has a nice little secret. If you set the min and max to 1 it will not be repeatable. So you'll just have a fieldset.
Vorto data type
In the Vorto data type we need to select which datatype we want make multilingual. In this case the data type is actually the Nested Content NewsDetached single fieldset which has the subheader and text properties. So both those properties will become multilingual.
News Item document type
On the News Item document type I've removed the subheader and text properties and replaced them with the Vorto NewsDetached data type.
News Item Content
A content page with the News Item document type now has the subheader and text property multilingual. You only have 1 language tab for both properties so they look grouped.
Rendering the multilingual properties
Now that we have a multilingual fieldset we need to render the data. On the News Item document type we have a property called "news" which is the Vorto NewsDetached data type. Vorto has an extension method called GetVortoValue which will check the current culture and returns the property of that culture. Nested Content usually returns an IEnumerable<IPublishedContent>, but because we're using a single fieldset it will return a IPublishedContent. So we can do the following:
@using Our.Umbraco.Vorto.Extensions
@inherits UmbracoTemplatePage
@{
var newsDetached = Model.Content.GetVortoValue<IPublishedContent>("news");
}
<p>@(newsDetached.GetPropertyValue<string>("subheader"))</p>
<p>@(newsDetached.GetPropertyValue<IHtmlString>("bodyText"))</p>
So the newsDetached variable now is a translated IPublishedContent which will have all the properties in the correct language. So you only need to use GetVortoValue once.
Using with the Models Builder
The Models Builder can generate strongly typed models based on the document type. Because NewsDetached is also a document type we also have a model for that. So it's possible to make the translated IPublishedContent strongly typed. We create a partial class in which we implement the property.
public partial class UmbNewsItem
{
[ImplementPropertyType("news")]
public Newsdetached News
{
get
{
var news = this.GetVortoValue<IPublishedContent>("news");
return news == null ? null : new Newsdetached(news);
}
}
}
Than in the code we can do this:
@using Umbraco.Extensions.Models
@inherits UmbracoTemplatePage
@{
var newsItem = Model.Content as UmbNewsItem;
var newsDetached = newsItem.News;
}
<p>@newsDetached.Subheader</p>
<p>@newsDetached.BodyText</p>
So the NewsDetached strongly typed model based on the document type now has the translated properties. This way of working is easy for developers and also gives a good experience for content editors.
Do's and don'ts
Using a Nested Content inside Vorto works pretty well, but there are some issues. You'll probably get into trouble with mandatory fields. Those will not work. It's better to not make any fields mandatory and just put checks in the code so you won't get any errors. Other than that everything should work. I've even put the Grid inside Nested Content which I put inside Vorto and it just works.
You can put Nested Content inside Vorto, but it doesn't work the other way around. If you've created a Nested Content and put a Vorto property on that you'll get errors.
Multilingual URL
I've explained how you can translate properties with Vorto and Nested Content, but the URL will stay the same. You could use a Vorto textstring and put the URL in there. Than with a UrlProvider you can change the URL. I've blogged about that last year. This topic also has some ideas about it.
Example project
I've created a working example which can be downloaded here: https://github.com/jbreuer/1-1-multilingual-example
It has a Visual Studio project which you can build. After that just start the website and it should work. It comes with a SQL CE database.
Backoffice credentials:
Username: admin
Password: testtest
Jeroen Breuer
Jeroen is on Twitter as @j_breuer