-
Notifications
You must be signed in to change notification settings - Fork 26
Multilingual support
Puck supports multi site and 1:1 approach to multilingual web sites.
for this approach, you have multiple site roots in the back office mapped to different domains. for example, the root level content HomeUK
might be your default so this can be mapped to *
, an asterisk mapping sets it as a wildcard meaning it's the default for all domains. then you might have another root named ContentJP
which you can map to the domain jp.domain.com
. in the localisation settings for these roots, they will be set to have the variant name of en-gb
and ja-jp
, respectively and content queries in your views will respect these settings and retrieve the correct language content.
you can also set different localisation settings further down the site tree so although HomeUK
might be set to the language variant en-gb
, HomeUK/News
could be set to a different language if you prefer. ¬¬
for this approach, you can simply have translations of all of your content under one site root. if you click the settings icon for a content item in the site tree, you will have the option to translate to one of the available languages you've set in the settings->languages page of the Backoffice.
in your views, you can then query for available translations (called variants) and show that translation based on a querystring parameter or cookie value. to get all the translations of any ViewModel
all you need to do is call Model.Variants()
. to get a specific variant, you can do the following:
var variant = new QueryHelper<T>()
.Id(Model.Id)
.Variant("en-gb")
.Get();
click here for more information about the QueryHelper
.
if you wanted to have 1:1 translations but have the current language used by Puck to be mapped by the domain/subdomain or some other custom method, you can pass the language you would like to use to Puck as an override to the default culture setting for that page.
by default, the HomeController
inherits from Pucks BaseController
and calls base.Puck()
in the Index
action to serve the current page.
in this approach, you could check what the subdomain is of the current request, for example en-gb.domain.com
and use that to pass the language to Puck. so you'd pass it like so:
public IActionResult Index()
{
var variantFromSubdomain = Request.Host.Host.Split(".")[0];
return base.Puck(variant:variantFromSubdomain);
}
likewise you could get the culture/variant from the querystring:
public IActionResult Index(string variantFromQuerystring=null)
{
return base.Puck(variant:variantFromQuerystring);
}
here the variant will be taken from the querystring if it exists, if null the current culture setting for that node will be used by default.
you could also add the culture to the end of the path, for example /news/tech/en-gb
then do the following:
public IActionResult Index()
{
var pathAndCultureSegment = Request.Path.ToString();
var path = pathAndCultureSegment.Substring(0, pathAndCultureSegment.LastIndexOf("/"));
var variant = pathAndCultureSegment.Substring(pathAndCultureSegment.LastIndexOf("/")).TrimEnd('/');
return base.Puck(path:path,variant:variant);
}
in the above example, the last segment of the url is used to get the Culture
or Variant
. it's then stripped from the path to get the actual path of the content and both the path and culture are passed to the base.Puck
method.
with any of the previous approaches shown where you're overriding the Culture
and passing it to base.Puck
, you can make sure you fallback to the default content if the translation for the overridden culture doesn't exist by doing the following:
public IActionResult Index()
{
var pathAndCultureSegment = Request.Path.ToString();
var path = pathAndCultureSegment.Substring(0, pathAndCultureSegment.LastIndexOf("/"));
var variant = pathAndCultureSegment.Substring(pathAndCultureSegment.LastIndexOf("/")).TrimEnd('/');
var result = base.Puck(path:path,variant:variant) as ViewResult;
if (result.Model == null)
return base.Puck();
else
return result;
}
in the example above, you first attempt to override the Culture
and check the result's Model
is null. if it is, it means Puck couldn't find the content with the override you specified and then you can return the default translation for the current page based on its Localisation
settings in the backoffice.
in your views when using QueryHelper
to query for content, you would then use the CurrentLanguage()
method of QueryHelper
to make sure that the content returned is of the current language.