// Copyright (c) Umbraco. // See LICENSE for more details. using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Mvc.Rendering; using Umbraco.Cms.Core.Models.Blocks; using Umbraco.Cms.Core.Models.PublishedContent; namespace Umbraco.Extensions; public static class BlockGridTemplateExtensions { public const string DefaultFolder = "blockgrid/"; public const string DefaultTemplate = "default"; public const string DefaultItemsTemplate = "items"; public const string DefaultItemAreasTemplate = "areas"; public const string DefaultItemAreaTemplate = "area"; #region Async /// /// Renders a block grid model into a grid layout /// /// /// By default this method uses a set of built-in partial views for rendering the blocks and areas in the grid model. /// These partial views are embedded in the static assets (Umbraco.Cms.StaticAssets), so they won't show up in the /// Views folder on your local disk. /// /// If you need to tweak the grid rendering output, you can copy the partial views from GitHub to your local disk. /// The partial views are found in "/src/Umbraco.Cms.StaticAssets/Views/Partials/blockgrid/" on GitHub and should /// be copied to "Views/Partials/BlockGrid/" on your local disk. /// /// public static async Task GetBlockGridHtmlAsync(this IHtmlHelper html, BlockGridModel? model, string template = DefaultTemplate) { if (model?.Count == 0) { return new HtmlString(string.Empty); } return await html.PartialAsync(DefaultFolderTemplate(template), model); } /// public static async Task GetBlockGridHtmlAsync(this IHtmlHelper html, IPublishedProperty property, string template = DefaultTemplate) => await GetBlockGridHtmlAsync(html, property.GetValue() as BlockGridModel, template); /// public static async Task GetBlockGridHtmlAsync(this IHtmlHelper html, IPublishedContent contentItem, string propertyAlias) => await GetBlockGridHtmlAsync(html, contentItem, propertyAlias, DefaultTemplate); public static async Task GetBlockGridHtmlAsync(this IHtmlHelper html, IPublishedContent contentItem, string propertyAlias, string template) { IPublishedProperty prop = GetRequiredProperty(contentItem, propertyAlias); return await GetBlockGridHtmlAsync(html, prop.GetValue() as BlockGridModel, template); } public static async Task GetBlockGridItemsHtmlAsync(this IHtmlHelper html, IEnumerable items, string template = DefaultItemsTemplate) => await html.PartialAsync(DefaultFolderTemplate(template), items); public static async Task GetBlockGridItemAreasHtmlAsync(this IHtmlHelper html, BlockGridItem item, string template = DefaultItemAreasTemplate) => await html.PartialAsync(DefaultFolderTemplate(template), item); public static async Task GetBlockGridItemAreaHtmlAsync(this IHtmlHelper html, BlockGridArea area, string template = DefaultItemAreaTemplate) => await html.PartialAsync(DefaultFolderTemplate(template), area); public static async Task GetBlockGridItemAreaHtmlAsync(this IHtmlHelper html, BlockGridItem item, string areaAlias, string template = DefaultItemAreaTemplate) { BlockGridArea? area = item.Areas.FirstOrDefault(a => a.Alias == areaAlias); if (area == null) { return new HtmlString(string.Empty); } return await GetBlockGridItemAreaHtmlAsync(html, area, template); } #endregion #region Sync /// public static IHtmlContent GetBlockGridHtml(this IHtmlHelper html, BlockGridModel? model, string template = DefaultTemplate) { if (model?.Count == 0) { return new HtmlString(string.Empty); } return html.Partial(DefaultFolderTemplate(template), model); } /// public static IHtmlContent GetBlockGridHtml(this IHtmlHelper html, IPublishedProperty property, string template = DefaultTemplate) => GetBlockGridHtml(html, property.GetValue() as BlockGridModel, template); /// public static IHtmlContent GetBlockGridHtml(this IHtmlHelper html, IPublishedContent contentItem, string propertyAlias) => GetBlockGridHtml(html, contentItem, propertyAlias, DefaultTemplate); public static IHtmlContent GetBlockGridHtml(this IHtmlHelper html, IPublishedContent contentItem, string propertyAlias, string template) { IPublishedProperty prop = GetRequiredProperty(contentItem, propertyAlias); return GetBlockGridHtml(html, prop.GetValue() as BlockGridModel, template); } public static IHtmlContent GetBlockGridItemsHtml(this IHtmlHelper html, IEnumerable items, string template = DefaultItemsTemplate) => html.Partial(DefaultFolderTemplate(template), items); public static IHtmlContent GetBlockGridItemAreasHtml(this IHtmlHelper html, BlockGridItem item, string template = DefaultItemAreasTemplate) => html.Partial(DefaultFolderTemplate(template), item); public static IHtmlContent GetBlockGridItemAreaHtml(this IHtmlHelper html, BlockGridArea area, string template = DefaultItemAreaTemplate) => html.Partial(DefaultFolderTemplate(template), area); public static IHtmlContent GetBlockGridItemAreaHtml(this IHtmlHelper html, BlockGridItem item, string areaAlias, string template = DefaultItemAreaTemplate) { BlockGridArea? area = item.Areas.FirstOrDefault(a => a.Alias == areaAlias); return area != null ? GetBlockGridItemAreaHtml(html, area, template) : new HtmlString(string.Empty); } #endregion private static string DefaultFolderTemplate(string template) => $"{DefaultFolder}{template}"; private static IPublishedProperty GetRequiredProperty(IPublishedContent contentItem, string propertyAlias) { ArgumentNullException.ThrowIfNull(propertyAlias); if (string.IsNullOrWhiteSpace(propertyAlias)) { throw new ArgumentException( "Value can't be empty or consist only of white-space characters.", nameof(propertyAlias)); } IPublishedProperty? property = contentItem.GetProperty(propertyAlias); if (property == null) { throw new InvalidOperationException("No property type found with alias " + propertyAlias); } return property; } }