1

I need to set context language by browser language (languages) and do a redirect to correct language version. I also need to exclude robots due to indexing of search engines.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Lukas Dvorak
  • 481
  • 4
  • 15

1 Answers1

6

I found article about "Browser Language Detection is Sitecore" from Mark Stiles, but it wasn't exactly what I wanted because he is overriding native functionality at all.

After several hours I created own (there are parts of Mark's code too) LanguageResolver using for detection of browser language with redirection if is needed and excluding robots.

public class LanguageResolver : Sitecore.Pipelines.HttpRequest.LanguageResolver
{
    public override void Process(Sitecore.Pipelines.HttpRequest.HttpRequestArgs args)
    {
        Assert.ArgumentNotNull(args, "args");
        Language lang = GetLanguageFromBrowser(args);
        if (lang != null)
        {
            Sitecore.Context.Language = lang;
            // if current language doesn't match with default site language, it will do a redirect
            if (Sitecore.Context.Language.Name != Sitecore.Context.Site.Language)
            {
                // do redirect
                UriBuilder uriBuilder = new UriBuilder(args.Context.Request.Url);
                uriBuilder.Path = Sitecore.Context.Language.Name + "/";
                HttpContext.Current.Response.Redirect(uriBuilder.Uri.ToString(), true);
                args.AbortPipeline();
            }
        }
        else
        {
            base.Process(args);
        }
    }
    /// <summary>
    /// Gets language from browser but only when language cookie doesn't exist yet and URL is related to homepage
    /// Logic taken from https://markstiles.net/Blog/2013/04/01/browser-language-detection-in-sitecore.aspx
    /// </summary>
    /// <param name="args"></param>
    /// <returns></returns>
    public Language GetLanguageFromBrowser(Sitecore.Pipelines.HttpRequest.HttpRequestArgs args)
    {
        // site must be inicialized, language si resolved only for homepage and a site must have in its configuration resolveBrowserLang="true" !
        if (IsBrowserLangDetectionAllowed(args))
        {
            // default site language
            Language defaultLangPrefix = LanguageManager.GetLanguage(Sitecore.Context.Site.Language);
            // gets browser languages
            string[] userLangs = args.Context.Request.UserLanguages;
            if (userLangs != null && userLangs.Any())
            {
                foreach (string userLang in userLangs)
                {
                    // gets first part where information about language is stored
                    string lang = userLang.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
                    if (!String.IsNullOrEmpty(lang))
                    {
                        Language scLang;
                        // if lang starts with the same letters as are in defaultLangPrefix
                        if (defaultLangPrefix != null && lang.StartsWith(defaultLangPrefix.CultureInfo.TwoLetterISOLanguageName))
                        {
                            scLang = defaultLangPrefix;
                        }
                        else
                        {
                            if (!Language.TryParse(lang, out scLang))
                            {
                                continue;
                            }
                        }
                        // then try to get the language item id from the language or two letter iso code
                        ID scLangId = LanguageManager.GetLanguageItemId(scLang, Sitecore.Context.Database);
                        if (ID.IsNullOrEmpty(scLangId))
                        {
                            //sometimes the language found is slightly different than official language item used in SC
                            scLang = LanguageManager.GetLanguage(scLang.CultureInfo.TwoLetterISOLanguageName);
                            scLangId = LanguageManager.GetLanguageItemId(scLang, Sitecore.Context.Database);
                        }
                        if (ID.IsNullOrEmpty(scLangId))
                        {
                            continue;
                        }
                        Item startItem = Sitecore.Context.Database.GetItem(Sitecore.Context.Site.StartPath, scLang);
                        //if you've got a version in this language then use that language
                        if (startItem != null && startItem.Versions.Count > 0)
                        {
                            return scLang;
                        }
                    }
                }
                // fallback language from site configuration
                return LanguageManager.GetLanguage(Sitecore.Context.Site.Properties["resolveBrowserFallbackLang"]);
            }
        }
        return null;
    }
    /// <summary>
    /// Determinates if detection is allowed
    /// </summary>
    /// <param name="args"></param>
    /// <returns></returns>
    protected bool IsBrowserLangDetectionAllowed(Sitecore.Pipelines.HttpRequest.HttpRequestArgs args)
    {
        // site must be defined
        return Sitecore.Context.Site != null
            // lang cookie is not already set
            && !args.Context.Request.Cookies.AllKeys.Contains(Sitecore.Context.Site.GetCookieKey("lang"))
            // URL is related to homepage
            && args.Context.Request.Url.AbsolutePath == "/"
            // site must have property resolveBrowserLang="true"
            && Sitecore.Context.Site.Properties["resolveBrowserLang"] == "true"
            // user agent is not robot
            && !Sitecore.Analytics.Configuration.AnalyticsSettings.Robots.ExcludeList.ContainsUserAgent(args.Context.Request.UserAgent);
    }
}

Client's request was only for homepage, so the script could be extended.

Lukas Dvorak
  • 481
  • 4
  • 15
  • You can "accept" your own answer by clicking on the "tick". This removes it from the unsolved question list in StackOverflow. – Brian Tompsett - 汤莱恩 Jun 01 '15 at 19:48
  • Updated link to ["Browser Language Detection is Sitecore" from Mark Stiles](https://markstiles.net/blog/2013/4/1/browser-language-detection-in-sitecore/) https://markstiles.net/blog/2013/4/1/browser-language-detection-in-sitecore/ – Annagram Feb 14 '18 at 17:18