Enforcing Sitecore Languages by Site

Wed Aug 22 2012

A question posted on SDN reminded me of a small but powerful pipeline processor we created for a customer that allows you to enforce what languages can be accessed on a particular Sitecore site. As the poster points out, by default Sitecore puts no restrictions on the languages that can be accessed for a given site. So for example, you may only want to allow accessing your Germany site in de-DE, because that's the only language for which you are populating content.

STEP 1 - The configuration element

On our site definition, we're going to add a new attribute, enabledLanguages. Values are pipe-delimited.

<site name="website" patch:after="site[@name='modules_website']"
    virtualFolder="/"
    physicalFolder="/"
    rootPath="/sitecore/content/sample"
    enabledLanguages="en|de-DE"
    startItem="/home"
    database="web"
    domain="extranet"
    allowDebug="true"
    cacheHtml="false"
    enablePreview="true"
    enableWebEdit="true"
    enableDebugger="true"
    disableClientData="false"
    formsRoot="{F1F7AAB6-C8CE-422F-A214-F610C109FA63}" />

STEP 2 - The extension method

This will allow us to access enabled languages from Sitecore.Context.Site.

namespace My.Extensions
{
    public static class SiteExtensions
    {
        private const string _enabledLanguagesAttributeName = "enabledLanguages";

        public static string[] GetEnabledLanguages(this SiteContext siteContext)
        {
            if (siteContext == null ||
            string.IsNullOrEmpty(siteContext.Properties[_enabledLanguagesAttributeName]))     
            {
                return new string[0];
            }
            return siteContext.Properties[_enabledLanguagesAttributeName].Split('|');
        }
    }
}

STEP 3 - The pipeline processor

This processor checks the context language against the site's enabled languages, and terminates request processing if the language is not permitted. Note that we don't enforce a 404 here ourselves, since in theory the default IIS 404 page should take over. YMMV depending on your configuration.

namespace My.Pipelines.HttpRequestBegin
{
    public class CountryLanguageEnforcer : HttpRequestProcessor
    {
        public override void Process(HttpRequestArgs args)
        {
            if (Sitecore.Context.Site == null || Sitecore.Context.Language == null)
            {
                return;
            }

            if (!Sitecore.Context.PageMode.IsNormal)
            {
                return;
            }

            var enabledLanguages = Sitecore.Context.Site.GetEnabledLanguages();
            if (enabledLanguages.Length == 0)
            {
                return;
            }

            if (!enabledLanguages.Contains(Sitecore.Context.Language.Name))
            {
                //don’t process URL. could also directly force 404 here
                args.AbortPipeline();
            }
        }
    }
}

STEP 4 - Configure the processor

Utilize an App_Config\Include file to patch the processor into the httpRequestBegin pipeline, after Sitecore has completed language resolution.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
        <pipelines>
            <httpRequestBegin>
                <processor patch:after="*[@type='Sitecore.Pipelines.HttpRequest.LanguageResolver, Sitecore.Kernel']" type="My.Pipelines.HttpRequestBegin.CountryLanguageEnforcer,My.Classes"/>
            </httpRequestBegin>
        </pipelines>
    </sitecore>
</configuration>

... and there you have it.

On each site, configure enabledLanguages as needed, based on the languages you are populating for the site.

Loading...
Nick Wesselman

Nick Wesselman started working professionally in software development just a few days after everyone realized we dodged a bullet with the Y2k bug. He’s worked as a Sitecore solution partner, Technology partner, and now for Sitecore itself. He lives with his wife, son, and daughter in Asheville, NC.