Thursday, August 20, 2015

Sitecore: Multisite Setup with Multilingual

This is a followup blog entry to the custom language fallback strategy located here:

http://mrstevenzhao.blogspot.com/2015/08/sitecore-custom-language-fallback.html

Background

Clients usually go the route of single-Sitecore instance, multi-site setup for the purposes of cutting costs and maximizing reusability of components.  This approach usually complicates development but there are loads of advantages as well, such as writing less code and less copy-and-pasting.

Scenario

A very realistic scenario in the corporate world is a large parent company with many different brands.  All the brands will have their own individual sites.  In the Sitecore world, each of these brand websites can be an individual site in the content tree.  But what about when each of these brands have multiple international versions?  It would be easy if we could just use the "sc_lang" parameter to switch languages but what if they need to be hosted under different domain name suffixes.  For example:

www.domain.com - main site
www.domain.fr - main site with French content
www.domain.com.au - main site with Australian English content

In this scenario, we don't want to create three website nodes in the content tree.  That would defeat the purpose of language fallback and content resusability.  The only way is to ensure all three sites are reading from the same node, except that depending on the hostname suffix, we choose the corresponding language content.

Setup

To start we must ensure that there is a place to associate different languages with different domain name suffixes.  To do this, you can modify the system language template to include a new field:



Then if you guess correctly, we would eventually have to query all the system languages for the value of the Domain Name Suffix field and value.  We COULD iterate item by item in this folder but the better way would be to create a custom Lucene index that contains all these items and their fields and values.  This part is up to you to create. 

As for defining the sites, you can either do it the out-of-the-box way and add to the <site> entries in the web.config file or you can do it the way I did it with dynamic configurations without having to modify any config files.

http://mrstevenzhao.blogspot.com/2014/04/sitecore-multi-site-setup-wo-updating.html

Solution

Eventually we will need a way to route the hostname in the browser to the correct context website with the corresponding context language.  This is a two step process:

1) Find the correct "parent" site, usually the ".com" version.
2) Find the content item for the language according to the domain name suffix.

Step one can be done in the SiteResolver processor of the HtttpRequestBegin pipeline.  It is best if you create a new custom version of this class or create a a derived version of the default one.  In a nutshell, you would have to:

a) Check the URL hostname and get the value of the name without the suffix.
b) Look through all the website node names without suffixes in the content tree and try to find a match with the value from step a.
c) If a node is found, then you have found the context site.

To enhance performance you can utilize HttpContext caching and custom Lucene indexes to store all website nodes so you can just query against an index instead of iterating though items in the tree.

Step two can be done by creating a custom LanguageResolver that is derived from the default LanguageResolver.  Once you set the context language, the ItemProvider that actually gets the language version of the content items will do everything automatically.  Basically, here are the steps for the custom LanguageResolver:

a) Check the url for the language parameter "sc_lang" to see if language is already being set manually.  If so then we just let the default behavior take place.
b) If not, then we check the domain name suffix. If the domain suffix matches any of the system languages on the value of the field "Domain Name Suffix", then we have found the matching language.  Set the context language to be that language using the ISO code.

Summary

This is the high-level implementation of the strategy.  We do not want to create site nodes for every single language of a domain so we have to check that the current hostname in the browser matches the "main" site hostname in the content tree.  We then take the suffix and determine which system language is mapped to that suffix and set the context language. 


No comments:

Post a Comment