I assume you have read Part 1 and Part 2 of this series so I won’t explain versioned layouts feature. I will only say that out of the box Experience Editor can only edit Final layout. To modify Shared portion of the presentation details you need Device Editor:
Or you can edit the field value directly the Chuck Norris style:
Solution
Our solution to the idiosyncrasies of the versioned layouts feature comes in three parts.
Experience Editor
First, SCORE now supports editing Shared part of the layout in Experience Editor. It works (and looks) very much like Edit/Preview with a session cookie value locking you in the mode you selected. It also works in both SPEAK and Sheer ribbons.
Best Practice
The next part is our best practice technique not to use all fours parts of the presentation details simultaneously. Learn more about why I think it may be confusing in Part 2 and decide whether you go Shared -> Shared -> Final
or Shared -> Final -> Final
route:
The former will be more natural for those migrating from previous versions to 8 as all your presentation will be in Shared fields (__Renderings
) anyway.
Validator
The last piece of the puzzle is a simple item validator to warn you when you violate the best practice. I simplified the code example for the blog post. You would probably consider items valid if they are single language and single version. You would also account for some combinations that are “weird” even with three parts of the layout (e.g. Shared + Final + Shared
, or Final + Shared + Final
– any combination where you switch between Shared
and Final
more than once):
using Sitecore; using Sitecore.Data.Fields; using Sitecore.Data.Items; using Sitecore.Data.Validators; namespace Score.Data.Validators.ItemValidators { public class VersionedLayoutValidator: StandardValidator { protected override ValidatorResult Evaluate() { Item item = GetItem(); if (item == null) { return ValidatorResult.Valid; } return DoEvaluate(item); } public virtual ValidatorResult DoEvaluate(Item item) { Field shared = item.Fields[FieldIDs.LayoutField]; Field final = item.Fields[FieldIDs.FinalLayoutField]; if (final.HasValue && !string.IsNullOrEmpty(final.GetStandardValue()) && shared.HasValue && !string.IsNullOrEmpty(shared.GetStandardValue())) { Text = GetText("You are not Chuck Norris, sorry!"); return GetFailedResult(ValidatorResult.Warning); } return ValidatorResult.Valid; } protected override ValidatorResult GetMaxValidatorResult() { return GetFailedResult(ValidatorResult.Warning); } public override string Name { get { return @"Versioned Layouts Best Practice Validator"; } } } }Cheers!