diff --git a/Sdl.Web.Common/Models/RegionModel.cs b/Sdl.Web.Common/Models/RegionModel.cs old mode 100644 new mode 100755 index 55b92cfb..d64a1fcf --- a/Sdl.Web.Common/Models/RegionModel.cs +++ b/Sdl.Web.Common/Models/RegionModel.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; using System.Linq; using Sdl.Web.Common.Configuration; - +using System.Text.RegularExpressions; +using System; + namespace Sdl.Web.Common.Models { /// @@ -54,7 +56,18 @@ public RegionModelSet Regions } } - + public String NameWithoutPostfix + { + get + { + var match = Regex.Match(Name, @"(.*)___\d+"); + if (match.Success) + { + return match.Groups[1].Value; + } + return Name; + } + } #region Constructors /// /// Initializes a new instance. @@ -80,6 +93,11 @@ public RegionModel(string name, string qualifiedViewName) } #endregion + public String GetNameWithPostfix(int counter) + { + return String.Format("{0}___{1}", this.Name, counter); + } + #region Overrides /// @@ -89,7 +107,7 @@ public RegionModel(string name, string qualifiedViewName) /// The XPM markup. public override string GetXpmMarkup(Localization localization) { - XpmRegion xpmRegion = localization.GetXpmRegionConfiguration(Name); + XpmRegion xpmRegion = localization.GetXpmRegionConfiguration(this.NameWithoutPostfix); if (xpmRegion == null) { return string.Empty; diff --git a/Sdl.Web.Tridion/Mapping/DefaultModelBuilder.cs b/Sdl.Web.Tridion/Mapping/DefaultModelBuilder.cs old mode 100644 new mode 100755 index 88af2323..77794578 --- a/Sdl.Web.Tridion/Mapping/DefaultModelBuilder.cs +++ b/Sdl.Web.Tridion/Mapping/DefaultModelBuilder.cs @@ -51,40 +51,24 @@ public virtual void BuildPageModel(ref PageModel pageModel, IPage page, IEnumera // Create Regions/Entities from Component Presentations IConditionalEntityEvaluator conditionalEntityEvaluator = SiteConfiguration.ConditionalEntityEvaluator; + RegionModel currentRegion = null; + Dictionary duplicateRegionCounter = new Dictionary(); foreach (IComponentPresentation cp in page.ComponentPresentations) { - MvcData cpRegionMvcData = GetRegionMvcData(cp); - string regionName = cpRegionMvcData.RegionName ?? cpRegionMvcData.ViewName; - RegionModel region; - if (regions.TryGetValue(regionName, out region)) - { - // Region already exists in Page Model; MVC data should match. - if (!region.MvcData.Equals(cpRegionMvcData)) - { - Log.Warn("Region '{0}' is defined with conflicting MVC data: [{1}] and [{2}]. Using the former.", region.Name, region.MvcData, cpRegionMvcData); - } - } - else - { - // Region does not exist in Page Model yet; create Region Model and add it. - region = CreateRegionModel(cpRegionMvcData); - regions.Add(region); - } - + currentRegion = GetRegionForEntity(regions, cp, currentRegion, duplicateRegionCounter); try { EntityModel entity = ModelBuilderPipeline.CreateEntityModel(cp, localization); - if (conditionalEntityEvaluator == null || conditionalEntityEvaluator.IncludeEntity(entity)) { - region.Entities.Add(entity); + currentRegion.Entities.Add(entity); } } catch (Exception ex) { // If there is a problem mapping an Entity, we replace it with an ExceptionEntity which holds the error details and carry on. Log.Error(ex); - region.Entities.Add(new ExceptionEntity(ex)); + currentRegion.Entities.Add(new ExceptionEntity(ex)); } } @@ -133,6 +117,56 @@ public virtual void BuildPageModel(ref PageModel pageModel, IPage page, IEnumera } } + private RegionModel GetRegionForEntity(RegionModelSet regions, IComponentPresentation cp, RegionModel currentRegion, Dictionary duplicateRegionCounter) + { + MvcData cpRegionMvcData = GetRegionMvcData(cp); + string regionName = cpRegionMvcData.RegionName ?? cpRegionMvcData.ViewName; + string currentRegionName = currentRegion!=null ? currentRegion.NameWithoutPostfix : null; + string duplicateRegionName = null; + RegionModel region = null; + //If we are still in the same region, reuse it, unless the mvc data is different, + //in which case we start a new region of the same name + if (regionName==currentRegionName) + { + if (currentRegion.MvcData.Equals(cpRegionMvcData)) + { + return currentRegion; + } + else + { + Log.Debug("Region '{0}' is defined with different MVC data: [{1}] and [{2}]. Starting a new region.", regionName, currentRegion.MvcData, cpRegionMvcData); + } + } + //We already had this region, but there has been something else inbetween, so we need to create a new (postfixed) one + if (regions.ContainsKey(regionName)) + { + int counter = 1; + if (duplicateRegionCounter.ContainsKey(regionName)) + { + counter = duplicateRegionCounter[regionName] + 1; + duplicateRegionCounter[regionName] = counter; + } + else + { + duplicateRegionCounter.Add(regionName, counter); + } + duplicateRegionName = regions[regionName].GetNameWithPostfix(counter); + } + //New region required + if (region == null) + { + // Region does not exist in Page Model yet; create Region Model and add it. + if (!String.IsNullOrEmpty(duplicateRegionName)) + { + cpRegionMvcData.RegionName = duplicateRegionName; + } + region = CreateRegionModel(cpRegionMvcData); + regions.Add(region); + currentRegion = region; + } + return region; + } + public virtual void BuildEntityModel(ref EntityModel entityModel, IComponentPresentation cp, Localization localization) { using (new Tracer(entityModel, cp, localization))