tirsdag den 11. november 2014

Why you shouldn't just hardcode X-UA-Compatible meta tag in your layout

Sometimes, people either hardcode the X-UA-Compatible meta tag in the <head> section of the page, or in the web.config file as a custom header.

I have seen this a few times now, and every time it breaks something (especially with versions of Sitecore before 7.2) .

The problem is, that doing it this way, you prevent Sitecore from changing it when it is needed for it's own tools to work (like the page editor).

Instead, what you should do, is add the following code to the Page_Load function of your layout:

if (Sitecore.Context.PageMode.IsNormal)
{
    Response.AddHeader("X-UA-Compatible", "IE=edge,chrome=1");
}

Now, the X-UA-Compatible indication is still sent to the browser, which knows how to handle it (since it can be told this both using headers and meta tags) - but both Preview and the Page Editor works like they should, since it doesn't get set.

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 :-)

Unable to close the rich text editor in page editor mode after applying Chrome 37 patch from Sitecore

A while ago, Google updated Chrome so it no longer supports the showModalDialog javascript function, which causes it to break Sitecore on Chrome (other browsers are following along soon, so if you aren't using Chrome, you still have to think about this issue).

To see if you are affected, please take a look at this knowledgebase article, and apply it if it is needed for your Sitecore version.

When the patch have been applied however, there is a new issue that is introduced, which is that you can not close the rich text editor in the page editor by clicking the buttons.

You can edit and save just fine, but the window does not close when it should (you can use the cross in the top right corner, but that is not userfriendly to have to force the users to do this).

There is a small fix for this issue:
  1. Open the “[Website]/sitecore/shell/Controls/Rich Text Editor/EditorPage.js” file.
  2. Replace the following line in the “scCloseEditor” method:
window.close();

With:

if (top._scDialogs.length != 0) {
       top.dialogClose();
} else {
       window.close();
}

This fixes the issue, so it once again is possible to have the dialogs closing when they should.