Enforcing Sitecore Languages by Site
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.