onsdag den 5. november 2014

Change item resolving to only find items that is in the current language

When developing solutions that has multiple languages, it is almost impossible to end up in a situation, where some of the content pages isn't translated to all the languages the website is avaliable in.

This ends up with some weird pages, that might just show stuff like "$name" in certian places (if that is what is written in the Standard Values for that field in that language).

To fix this issue, so the frontend behaves as if the page doesn't even exist in the frontend, if it isn't there in the current language, we create a small HttpRequest processor.

So, first create a new class in Visual Studio, and enter the following code:

public class EnsureItemLanguage : HttpRequestProcessor
{
    public override void Process(HttpRequestArgs args)
    {
        if (args == null)
        {
            throw new ArgumentNullException("args");
        }

        if (Sitecore.Context.Item == null || Sitecore.Context.Database == null)
        {
            return;
        }

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

        if (Sitecore.Context.Database.Name != "master" && Sitecore.Context.Database.Name != "web")
        {
            return;
        }

        if (!Sitecore.Context.Item.Paths.FullPath.StartsWith("/sitecore/content", StringComparison.InvariantCultureIgnoreCase))
        {
            return;
        }

        if (!DoesItemExistInLanguage(Sitecore.Context.Item, Sitecore.Context.Item.Language))
        {
            Sitecore.Context.Item = null;
        }
    }

    private static bool DoesItemExistInLanguage(Item item, Language language)
    {
        if (item == null)
        {
            throw new ArgumentNullException("item");
        }

        if (language == null)
        {
            throw new ArgumentNullException("language");
        }

        return Array.Exists(item.Versions.GetVersions(true), version => version.Language == language);
    }
}

This resets the Sitecore.Context.Item to null if the current item does not exist in the current language.

To make this work, you must also create an include file, to make this load after the normal ItemResolver.

To do this, create an include config file, and add the following to it:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:x="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <httpRequestBegin>
        <processor type="Namespace.Classname, Assembly" patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel']"/>
      </httpRequestBegin>
    </pipelines>
  </sitecore>
</configuration>

Where Namespace, Classname and Assembly has been replaced with your own values.

That is all that is needed to do this :-)

Ingen kommentarer:

Send en kommentar