Sitecore Base Layouts Part II

Learn how Base Layouts, which were introduced in an earlier post, can be updated to support versioned layout in Sitecore 8.

In my previous post, I introduced the concept of Base Layouts.  If you haven’t read that post yet, please do so now.  I’ll wait…

Ready? Then, let’s get started.

If you were paying attention to the first post, you may have noticed that I used an extension method field.IsLayoutField(). In the Sitecore 7 version, that method looks like this:

public static bool IsLayoutField(this Field field)
  return field.ID == FieldIDs.LayoutField;

The Sitecore 8 version looks like this:

public static bool IsLayoutField(this Field field)
  return field.ID == FieldIDs.LayoutField
              || field.ID == FieldIDs.FinalLayoutField;

That’s it. Post done.


...ok, not quite. Actually, I was quite surprised to find out how easily Base Layouts were adapted to Sitecore 8. While this really is the only change needed to get the core functionality working, we do need to consider real world usage.  

Pavel Veller wrote a series of posts earlier this year titled Sitecore 8. Versioned Layouts – Mixed Feelings (part 1, part 2, part 3). I highly recommend that you read them. In parts 1 and 2 he presents two issues related to the versioned layouts. The issue discussed in part 1 is resolved in Sitecore 8.1. The issue he raises in part 2 merits more discussion, particularly in the context of base layouts.

Pavel observed that applying a shared layout delta over a versioned layout value from a standard values item could lead to unpredictable and undesirable results. This potential issue is amplified when you can have a chain of several base layouts. To resolve this issue we can do a little validation when a user selects a new base layout:

public bool CreatesVersioningConflict(
  Item item,
  Item baseLayoutItem)
  var itemLayout = item.Fields[FieldIDs.LayoutField]
               .GetValue(false, false);
  return !string.IsNullOrWhiteSpace(itemLayout)
      && XmlPatchUtils.IsXmlPatch(itemLayout)
      && !string.IsNullOrWhiteSpace(
                  .GetValue(false, false));

Note that this is a bit less stringent than Pavel’s validator. It only fails the validation if the item has a delta in the shared layout field and the selected base layout has a value in the final layout field.

I was hoping that the new pipelines introduced in Sitecore 8.1 (getFieldValue or getLayoutSourceFields) would allow the code for Base Layouts to be simplified. Unfortunately, that does not appear to be the case. It seems that using those pipelines would only complicate matters. The 8.0 version does continue to work for 8.1, though.

Sitecore development, Sitecore custom code


Add a Comment


Please confirm you are human by typing the text you see in this image:

Pavel Veller said: 11/12/2015 at 12:09 PM

Hey Ben, good posts! One thing I would note is that layout can be *empty* when its string value is not. Try resetting layout field via Reset and you will see what I mean. An empty layout can also be an empty XML with three device nodes but no renderings in the.

Ben Golden said: 11/12/2015 at 12:22 PM

Thanks for the note, Pavel. I'll definitely take a closer look at that.

Mrunal Brahmbhatt said: 11/12/2015 at 4:13 PM

Hi Ben,

I raised similar issue with John West.

Doing multiple times delta generated undesired result.

Ben Golden said: 11/13/2015 at 11:34 AM

Hi Mrunal. I looked at your comment on John's post. I'm not sure if I fully understand the problem you had with the solution you were using before, but this may avoid the issue since it does not need to explicitly caclulate/merge layout deltas. If you try this out, let me know how it goes.

Mrunal Brahmbhatt said: 12/9/2015 at 11:57 PM

I will implement and let you know, but this sounds really good approach.