Skip to content

Instantly share code, notes, and snippets.

@trnktms
Created February 27, 2024 09:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trnktms/e63012737070780151a7156d306c4b00 to your computer and use it in GitHub Desktop.
Save trnktms/e63012737070780151a7156d306c4b00 to your computer and use it in GitHub Desktop.
public abstract class LayoutBuilderBase<T> : ApiContentBuilderBase<T> where T : IApiContent
{
private const string LayoutPropertyKey = "layout";
protected readonly IEnumerable<IComponentResolver> ComponentResolvers;
protected readonly IApiPublishedContentCache ApiPublishedContentCache;
protected LayoutBuilderBase(
IApiContentNameProvider apiContentNameProvider,
IApiContentRouteBuilder apiContentRouteBuilder,
IOutputExpansionStrategyAccessor outputExpansionStrategyAccessor,
IEnumerable<IComponentResolver> componentResolvers,
IApiPublishedContentCache apiPublishedContentCache)
: base(apiContentNameProvider, apiContentRouteBuilder, outputExpansionStrategyAccessor)
{
ComponentResolvers = componentResolvers;
ApiPublishedContentCache = apiPublishedContentCache;
}
public override T? Build(IPublishedContent content)
{
var currentItem = base.Build(content);
if (currentItem == null)
{
return currentItem;
}
if (LayoutPropertyKey == null || currentItem.Properties[LayoutPropertyKey] == null)
{
return currentItem;
}
var currentLayout = currentItem.Properties[LayoutPropertyKey] as ApiBlockGridModel;
if (currentLayout?.Items == null || !currentLayout.Items.Any())
{
return currentItem;
}
var currentAreas = new List<ApiBlockGridArea>(currentLayout.Items.First().Areas ?? Array.Empty<ApiBlockGridArea>());
ResolvePreComponents(content, LayoutPropertyKey, ref currentAreas);
ResolvePostComponents(content, LayoutPropertyKey, ref currentAreas);
var currentLayoutItems = new List<ApiBlockGridItem>(currentLayout.Items);
currentLayoutItems[0] = new ApiBlockGridItem(
currentLayoutItems[0].Content,
currentLayoutItems[0].Settings,
currentLayoutItems[0].RowSpan,
currentLayoutItems[0].ColumnSpan,
currentLayoutItems[0].AreaGridColumns,
currentAreas);
var composedLayout = new ApiBlockGridModel(currentLayout.GridColumns, currentLayoutItems);
currentItem.Properties[LayoutPropertyKey] = composedLayout;
return currentItem;
}
private void ResolvePreComponents(IPublishedContent content, string layoutPropertyKey, ref List<ApiBlockGridArea> currentAreas)
{
foreach (var componentResolver in ComponentResolvers.Where(x => x.Order < 0).OrderByDescending(x => x.Order))
{
var partialPageAreas = GetPartialPageAreas(componentResolver, content, layoutPropertyKey);
if (partialPageAreas == null)
{
continue;
}
foreach (var area in partialPageAreas)
{
var foundArea = currentAreas.FirstOrDefault(a => a.Alias == area.Alias);
if (foundArea != null)
{
var index = currentAreas.IndexOf(foundArea);
var tempItems = foundArea.Items.ToList();
tempItems.InsertRange(0, area.Items);
currentAreas[index] = new ApiBlockGridArea(foundArea.Alias, foundArea.RowSpan, foundArea.ColumnSpan, tempItems);
}
else
{
currentAreas.Insert(0, area);
}
}
}
}
private void ResolvePostComponents(IPublishedContent content, string layoutPropertyKey, ref List<ApiBlockGridArea> currentAreas)
{
foreach (var componentResolver in ComponentResolvers.Where(x => x.Order >= 0).OrderBy(x => x.Order))
{
var partialPageAreas = GetPartialPageAreas(componentResolver, content, layoutPropertyKey);
if (partialPageAreas == null)
{
continue;
}
foreach (var area in partialPageAreas)
{
var foundArea = currentAreas.FirstOrDefault(a => a.Alias == area.Alias);
if (foundArea != null)
{
var index = currentAreas.IndexOf(foundArea);
var tempItems = foundArea.Items.ToList();
tempItems.AddRange(area.Items);
currentAreas[index] = new ApiBlockGridArea(foundArea.Alias, foundArea.RowSpan, foundArea.ColumnSpan, tempItems);
}
else
{
currentAreas.Add(area);
}
}
}
}
private IEnumerable<ApiBlockGridArea>? GetPartialPageAreas(IComponentResolver componentResolver, IPublishedContent content, string layoutPropertyKey)
{
var partialPage = base.Build(componentResolver.ResolveContent(content));
if (partialPage == null)
{
return null;
}
var partialPageLayout = partialPage.Properties[layoutPropertyKey] as ApiBlockGridModel;
var partialPageAreas = partialPageLayout?.Items?.First().Areas;
if (partialPageAreas == null)
{
return null;
}
return partialPageAreas;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment