Skip to content
Open
24 changes: 21 additions & 3 deletions Sdl.Web.Common/Models/RegionModel.cs
100644 → 100755
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
Expand Down Expand Up @@ -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
/// <summary>
/// Initializes a new <see cref="RegionModel"/> instance.
Expand All @@ -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

/// <summary>
Expand All @@ -89,7 +107,7 @@ public RegionModel(string name, string qualifiedViewName)
/// <returns>The XPM markup.</returns>
public override string GetXpmMarkup(Localization localization)
{
XpmRegion xpmRegion = localization.GetXpmRegionConfiguration(Name);
XpmRegion xpmRegion = localization.GetXpmRegionConfiguration(this.NameWithoutPostfix);
if (xpmRegion == null)
{
return string.Empty;
Expand Down
76 changes: 55 additions & 21 deletions Sdl.Web.Tridion/Mapping/DefaultModelBuilder.cs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, int> duplicateRegionCounter = new Dictionary<string, int>();
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));
}
}

Expand Down Expand Up @@ -133,6 +117,56 @@ public virtual void BuildPageModel(ref PageModel pageModel, IPage page, IEnumera
}
}

private RegionModel GetRegionForEntity(RegionModelSet regions, IComponentPresentation cp, RegionModel currentRegion, Dictionary<String,int> 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);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that now we can have duplicate regions, a change in MVC data can simply trigger a new region of the same name. This ties in nicely with PR #29 which allows regions to be configurable via CT metadata. In this case we would want to start a new region if the region route values were different

}
}
//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))
Expand Down