diff --git a/src/OrchardCore.Modules/OrchardCore.ContentFields/Media/MediaShapes.cs b/src/OrchardCore.Modules/OrchardCore.ContentFields/Media/MediaShapes.cs index 962097f31ef..64e362deb59 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentFields/Media/MediaShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentFields/Media/MediaShapes.cs @@ -1,18 +1,18 @@ -using OrchardCore.DisplayManagement; +using System.Threading.Tasks; using OrchardCore.DisplayManagement.Descriptors; using OrchardCore.Modules; namespace OrchardCore.ContentFields.Media { [RequireFeatures("OrchardCore.Media")] - public class MediaShapes : IShapeTableProvider + public class MediaShapes : ShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("HtmlField_Edit") .OnDisplaying(displaying => { - IShape editor = displaying.Shape; + var editor = displaying.Shape; if (editor.Metadata.Type == "HtmlField_Edit__Wysiwyg") { @@ -24,6 +24,8 @@ public void Discover(ShapeTableBuilder builder) editor.Metadata.Wrappers.Add("Media_Wrapper__HtmlField"); } }); + + return ValueTask.CompletedTask; } } } diff --git a/src/OrchardCore.Modules/OrchardCore.ContentFields/Views/YoutubeFieldSetting.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.ContentFields/Views/YoutubeFieldSetting.Edit.cshtml index 1316d842a23..ab9f44f60ad 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentFields/Views/YoutubeFieldSetting.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.ContentFields/Views/YoutubeFieldSetting.Edit.cshtml @@ -1,11 +1,5 @@ -@model OrchardCore.ContentFields.Settings.YoutubeFieldSettings -@using OrchardCore.ContentFields.Settings +@model YoutubeFieldSettings -@inject OrchardCore.DisplayManagement.Theming.IThemeManager ThemeManager -@inject OrchardCore.DisplayManagement.Descriptors.IShapeTableManager ShapeTableManager -@{ - -}
diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditField.cshtml b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditField.cshtml index 93de462e449..101112342e1 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditField.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditField.cshtml @@ -10,7 +10,7 @@ @{ var theme = await ThemeManager.GetThemeAsync(); - var shapeTable = ShapeTableManager.GetShapeTable(theme?.Id); + var shapeTable = await ShapeTableManager.GetShapeTableAsync(theme?.Id); var editorShapes = shapeTable.Bindings.Keys.Where(x => x.StartsWith(Model.PartFieldDefinition.FieldDefinition.Name + "_Option__", StringComparison.OrdinalIgnoreCase) || x.Equals(Model.PartFieldDefinition.FieldDefinition.Name + "_Option", StringComparison.OrdinalIgnoreCase)); var displayShapes = shapeTable.Bindings.Keys.Where(x => x.StartsWith(Model.PartFieldDefinition.FieldDefinition.Name + "_DisplayOption__", StringComparison.OrdinalIgnoreCase) || x.Equals(Model.PartFieldDefinition.FieldDefinition.Name + "_DisplayOption", StringComparison.OrdinalIgnoreCase)); var returnUrl = ViewData["returnUrl"]?.ToString(); diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditTypePart.cshtml b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditTypePart.cshtml index 7af2e937017..a5b28618d77 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditTypePart.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/Admin/EditTypePart.cshtml @@ -8,7 +8,7 @@ @{ var typePart = Model.TypePartDefinition; var theme = await ThemeManager.GetThemeAsync(); - var shapeTable = ShapeTableManager.GetShapeTable(theme?.Id); + var shapeTable = await ShapeTableManager.GetShapeTableAsync(theme?.Id); var displayShapes = shapeTable.Bindings.Keys.Where(x => x.StartsWith(Model.TypePartDefinition.PartDefinition.Name + "_DisplayOption__", StringComparison.OrdinalIgnoreCase) || x.Equals(Model.TypePartDefinition.PartDefinition.Name + "_DisplayOption", StringComparison.OrdinalIgnoreCase)); var editorShapes = shapeTable.Bindings.Keys.Where(x => x.StartsWith(Model.TypePartDefinition.PartDefinition.Name + "_Option__", StringComparison.OrdinalIgnoreCase) || x.Equals(Model.TypePartDefinition.PartDefinition.Name + "_Option", StringComparison.OrdinalIgnoreCase)); } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Shapes.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Shapes.cs index 67683ad9fa6..de392d1385b 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Shapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Shapes.cs @@ -1,4 +1,4 @@ -using System; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using OrchardCore.ContentManagement; using OrchardCore.ContentManagement.Display; @@ -9,9 +9,9 @@ namespace OrchardCore.Contents { - public class Shapes : IShapeTableProvider + public class Shapes : ShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("Content") .OnDisplaying(displaying => @@ -91,8 +91,10 @@ public void Discover(ShapeTableBuilder builder) displayShape.Metadata.Alternates.Add(alternate); } - await context.Shape.AddAsync(displayShape, ""); + await context.Shape.AddAsync(displayShape, string.Empty); }); + + return ValueTask.CompletedTask; } } } diff --git a/src/OrchardCore.Modules/OrchardCore.Demo/Shapes/DemoShapeProvider.cs b/src/OrchardCore.Modules/OrchardCore.Demo/Shapes/DemoShapeProvider.cs index f3f84a7b713..9604d50603a 100644 --- a/src/OrchardCore.Modules/OrchardCore.Demo/Shapes/DemoShapeProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.Demo/Shapes/DemoShapeProvider.cs @@ -1,16 +1,19 @@ using System.Text; +using System.Threading.Tasks; using Microsoft.AspNetCore.Html; namespace OrchardCore.DisplayManagement.Descriptors { - public class DemoShapeProvider : IShapeTableProvider, IShapeAttributeProvider + public class DemoShapeProvider : ShapeTableProvider, IShapeAttributeProvider { - public void Discover(ShapeTableBuilder builder) + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("Foo") .OnDisplaying(displaying => displaying.ChildContent = new HtmlString("

Hi

") ); + + return ValueTask.CompletedTask; } [Shape] diff --git a/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Services/LiquidShapes.cs b/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Services/LiquidShapes.cs index 3ec47c7bc9d..acb857d1ed1 100644 --- a/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Services/LiquidShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Facebook/Widgets/Services/LiquidShapes.cs @@ -9,31 +9,27 @@ using OrchardCore.Liquid; using OrchardCore.Modules; -namespace OrchardCore.Facebook.Widgets.Services +namespace OrchardCore.Facebook.Widgets.Services; + +[Feature(FacebookConstants.Features.Widgets)] +public class LiquidShapes(HtmlEncoder htmlEncoder) : ShapeTableProvider { - [Feature(FacebookConstants.Features.Widgets)] - public class LiquidShapes : IShapeTableProvider - { - private readonly HtmlEncoder _htmlEncoder; + private readonly HtmlEncoder _htmlEncoder = htmlEncoder; - public LiquidShapes(HtmlEncoder htmlEncoder) - { - _htmlEncoder = htmlEncoder; - } + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) + { + builder.Describe("FacebookPluginPart").OnProcessing(BuildViewModelAsync); + builder.Describe("FacebookPluginPart_Summary").OnProcessing(BuildViewModelAsync); - private async Task BuildViewModelAsync(ShapeDisplayContext shapeDisplayContext) - { - var model = shapeDisplayContext.Shape as FacebookPluginPartViewModel; - var liquidTemplateManager = shapeDisplayContext.ServiceProvider.GetRequiredService(); + return ValueTask.CompletedTask; + } - model.Html = await liquidTemplateManager.RenderStringAsync(model.FacebookPluginPart.Liquid, _htmlEncoder, shapeDisplayContext.DisplayContext.Value, - new Dictionary() { ["ContentItem"] = new ObjectValue(model.ContentItem) }); - } + private async Task BuildViewModelAsync(ShapeDisplayContext shapeDisplayContext) + { + var model = shapeDisplayContext.Shape as FacebookPluginPartViewModel; + var liquidTemplateManager = shapeDisplayContext.ServiceProvider.GetRequiredService(); - public void Discover(ShapeTableBuilder builder) - { - builder.Describe("FacebookPluginPart").OnProcessing(BuildViewModelAsync); - builder.Describe("FacebookPluginPart_Summary").OnProcessing(BuildViewModelAsync); - } + model.Html = await liquidTemplateManager.RenderStringAsync(model.FacebookPluginPart.Liquid, _htmlEncoder, shapeDisplayContext.DisplayContext.Value, + new Dictionary() { ["ContentItem"] = new ObjectValue(model.ContentItem) }); } } diff --git a/src/OrchardCore.Modules/OrchardCore.Html/Media/MediaShapes.cs b/src/OrchardCore.Modules/OrchardCore.Html/Media/MediaShapes.cs index 66752dfc33a..80d7f65d285 100644 --- a/src/OrchardCore.Modules/OrchardCore.Html/Media/MediaShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Html/Media/MediaShapes.cs @@ -1,28 +1,30 @@ +using System.Threading.Tasks; using OrchardCore.DisplayManagement.Descriptors; using OrchardCore.Modules; -namespace OrchardCore.Html.Media +namespace OrchardCore.Html.Media; + +[RequireFeatures("OrchardCore.Media")] +public class MediaShapes : ShapeTableProvider { - [RequireFeatures("OrchardCore.Media")] - public class MediaShapes : IShapeTableProvider + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { - public void Discover(ShapeTableBuilder builder) - { - builder.Describe("HtmlBodyPart_Edit") - .OnDisplaying(displaying => + builder.Describe("HtmlBodyPart_Edit") + .OnDisplaying(displaying => + { + var editor = displaying.Shape; + + if (editor.Metadata.Type == "HtmlBodyPart_Edit__Wysiwyg") { - var editor = displaying.Shape; + editor.Metadata.Wrappers.Add("Media_Wrapper__HtmlBodyPart"); + } - if (editor.Metadata.Type == "HtmlBodyPart_Edit__Wysiwyg") - { - editor.Metadata.Wrappers.Add("Media_Wrapper__HtmlBodyPart"); - } + if (editor.Metadata.Type == "HtmlBodyPart_Edit__Trumbowyg") + { + editor.Metadata.Wrappers.Add("Media_Wrapper__HtmlBodyPart"); + } + }); - if (editor.Metadata.Type == "HtmlBodyPart_Edit__Trumbowyg") - { - editor.Metadata.Wrappers.Add("Media_Wrapper__HtmlBodyPart"); - } - }); - } + return ValueTask.CompletedTask; } } diff --git a/src/OrchardCore.Modules/OrchardCore.Liquid/Services/LiquidShapes.cs b/src/OrchardCore.Modules/OrchardCore.Liquid/Services/LiquidShapes.cs index 4602477a926..2744e73c4fd 100644 --- a/src/OrchardCore.Modules/OrchardCore.Liquid/Services/LiquidShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Liquid/Services/LiquidShapes.cs @@ -8,31 +8,36 @@ using OrchardCore.Liquid.ViewModels; using OrchardCore.Modules; -namespace OrchardCore.Liquid.Services +namespace OrchardCore.Liquid.Services; + +[RequireFeatures("OrchardCore.Contents")] +public class LiquidShapes(HtmlEncoder htmlEncoder) : ShapeTableProvider { - [RequireFeatures("OrchardCore.Contents")] - public class LiquidShapes : IShapeTableProvider - { - private readonly HtmlEncoder _htmlEncoder; + private readonly HtmlEncoder _htmlEncoder = htmlEncoder; - public LiquidShapes(HtmlEncoder htmlEncoder) - { - _htmlEncoder = htmlEncoder; - } + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) + { + builder.Describe("LiquidPart").OnProcessing(BuildViewModelAsync); + builder.Describe("LiquidPart_Summary").OnProcessing(BuildViewModelAsync); - private async Task BuildViewModelAsync(ShapeDisplayContext shapeDisplayContext) - { - var model = shapeDisplayContext.Shape as LiquidPartViewModel; - var liquidTemplateManager = shapeDisplayContext.ServiceProvider.GetRequiredService(); + return ValueTask.CompletedTask; + } - model.Html = await liquidTemplateManager.RenderStringAsync(model.LiquidPart.Liquid, _htmlEncoder, shapeDisplayContext.DisplayContext.Value, - new Dictionary() { ["ContentItem"] = new ObjectValue(model.ContentItem) }); - } + private async Task BuildViewModelAsync(ShapeDisplayContext shapeDisplayContext) + { + var model = shapeDisplayContext.Shape as LiquidPartViewModel; - public void Discover(ShapeTableBuilder builder) + if (model?.LiquidPart is null) { - builder.Describe("LiquidPart").OnProcessing(BuildViewModelAsync); - builder.Describe("LiquidPart_Summary").OnProcessing(BuildViewModelAsync); + return; } + + var liquidTemplateManager = shapeDisplayContext.ServiceProvider.GetRequiredService(); + + model.Html = await liquidTemplateManager.RenderStringAsync(model.LiquidPart.Liquid, _htmlEncoder, shapeDisplayContext.DisplayContext.Value, + new Dictionary() + { + ["ContentItem"] = new ObjectValue(model.ContentItem) + }); } } diff --git a/src/OrchardCore.Modules/OrchardCore.Markdown/Media/MediaShapes.cs b/src/OrchardCore.Modules/OrchardCore.Markdown/Media/MediaShapes.cs index b4bcacc2c4a..937a540786c 100644 --- a/src/OrchardCore.Modules/OrchardCore.Markdown/Media/MediaShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Markdown/Media/MediaShapes.cs @@ -1,34 +1,36 @@ +using System.Threading.Tasks; using OrchardCore.DisplayManagement.Descriptors; using OrchardCore.Modules; -namespace OrchardCore.Markdown.Media +namespace OrchardCore.Markdown.Media; + +[RequireFeatures("OrchardCore.Media")] +public class MediaShapes : ShapeTableProvider { - [RequireFeatures("OrchardCore.Media")] - public class MediaShapes : IShapeTableProvider + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { - public void Discover(ShapeTableBuilder builder) - { - builder.Describe("MarkdownBodyPart_Edit") - .OnDisplaying(displaying => + builder.Describe("MarkdownBodyPart_Edit") + .OnDisplaying(displaying => + { + var editor = displaying.Shape; + + if (editor.Metadata.Type == "MarkdownBodyPart_Edit__Wysiwyg") { - var editor = displaying.Shape; + editor.Metadata.Wrappers.Add("Media_Wrapper__MarkdownBodyPart"); + } + }); - if (editor.Metadata.Type == "MarkdownBodyPart_Edit__Wysiwyg") - { - editor.Metadata.Wrappers.Add("Media_Wrapper__MarkdownBodyPart"); - } - }); + builder.Describe("MarkdownField_Edit") + .OnDisplaying(displaying => + { + var editor = displaying.Shape; - builder.Describe("MarkdownField_Edit") - .OnDisplaying(displaying => + if (editor.Metadata.Type == "MarkdownField_Edit__Wysiwyg") { - var editor = displaying.Shape; + editor.Metadata.Wrappers.Add("Media_Wrapper__MarkdownBodyPart"); + } + }); - if (editor.Metadata.Type == "MarkdownField_Edit__Wysiwyg") - { - editor.Metadata.Wrappers.Add("Media_Wrapper__MarkdownBodyPart"); - } - }); - } + return ValueTask.CompletedTask; } } diff --git a/src/OrchardCore.Modules/OrchardCore.Menu/MenuShapes.cs b/src/OrchardCore.Modules/OrchardCore.Menu/MenuShapes.cs index 7ca2c0b6fac..34f54d61df3 100644 --- a/src/OrchardCore.Modules/OrchardCore.Menu/MenuShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Menu/MenuShapes.cs @@ -1,5 +1,5 @@ -using System; using System.Text; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using OrchardCore.ContentManagement; using OrchardCore.DisplayManagement; @@ -11,9 +11,9 @@ namespace OrchardCore.Menu { - public class MenuShapes : IShapeTableProvider + public class MenuShapes : ShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("Menu") .OnProcessing(async context => @@ -174,6 +174,8 @@ public void Discover(ShapeTableBuilder builder) menuItem.Metadata.Alternates.Add("MenuItemLink__" + differentiator + "__" + encodedContentType + "__level__" + level); } }); + + return ValueTask.CompletedTask; } /// diff --git a/src/OrchardCore.Modules/OrchardCore.Navigation/NavigationShapes.cs b/src/OrchardCore.Modules/OrchardCore.Navigation/NavigationShapes.cs index 3e90991677e..d984364033c 100644 --- a/src/OrchardCore.Modules/OrchardCore.Navigation/NavigationShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Navigation/NavigationShapes.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; @@ -9,9 +10,9 @@ namespace OrchardCore.Navigation { - public class NavigationShapes : IShapeTableProvider + public class NavigationShapes : ShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("Navigation") .OnDisplaying(displaying => @@ -103,6 +104,8 @@ public void Discover(ShapeTableBuilder builder) menuItem.Metadata.Alternates.Add("NavigationItemLink__" + encodedMenuName); menuItem.Metadata.Alternates.Add("NavigationItemLink__" + encodedMenuName + "__level__" + level); }); + + return ValueTask.CompletedTask; } } } diff --git a/src/OrchardCore.Modules/OrchardCore.Navigation/PagerShapesTableProvider.cs b/src/OrchardCore.Modules/OrchardCore.Navigation/PagerShapesTableProvider.cs index 3292e2df2e6..498d967ecc7 100644 --- a/src/OrchardCore.Modules/OrchardCore.Navigation/PagerShapesTableProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.Navigation/PagerShapesTableProvider.cs @@ -17,9 +17,9 @@ namespace OrchardCore.Navigation { - public class PagerShapesTableProvider : IShapeTableProvider + public class PagerShapesTableProvider : ShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("Pager") .OnCreated(created => @@ -127,6 +127,8 @@ public void Discover(ShapeTableBuilder builder) displaying.Shape.Metadata.Alternates.Add("Pager_Links__" + pagerId.EncodeAlternateElement()); } }); + + return ValueTask.CompletedTask; } } diff --git a/src/OrchardCore.Modules/OrchardCore.Placements/Services/PlacementProvider.cs b/src/OrchardCore.Modules/OrchardCore.Placements/Services/PlacementProvider.cs index 0b6c04745a0..9c4fd14cc4d 100644 --- a/src/OrchardCore.Modules/OrchardCore.Placements/Services/PlacementProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.Placements/Services/PlacementProvider.cs @@ -56,7 +56,7 @@ public PlacementInfo ResolvePlacement(ShapePlacementContext placementContext) Func predicate = ctx => CheckFilter(ctx, placementRule); - if (filters.Any()) + if (filters.Count > 0) { predicate = filters.Aggregate(predicate, BuildPredicate); } diff --git a/src/OrchardCore.Modules/OrchardCore.Taxonomies/TermShapes.cs b/src/OrchardCore.Modules/OrchardCore.Taxonomies/TermShapes.cs index 6e34edcb81c..9d4774d0208 100644 --- a/src/OrchardCore.Modules/OrchardCore.Taxonomies/TermShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Taxonomies/TermShapes.cs @@ -1,7 +1,7 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json.Linq; using OrchardCore.ContentManagement; @@ -14,9 +14,9 @@ namespace OrchardCore.Taxonomies { - public class TermShapes : IShapeTableProvider + public class TermShapes : ShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { // Add standard alternates to a TermPart because it is rendered by a content display driver not a part display driver. builder.Describe("TermPart") @@ -25,7 +25,7 @@ public void Discover(ShapeTableBuilder builder) var viewModel = context.Shape as TermPartViewModel; var contentType = viewModel?.ContentItem?.ContentType; - var displayTypes = new[] { "", "_" + context.Shape.Metadata.DisplayType }; + var displayTypes = new[] { string.Empty, "_" + context.Shape.Metadata.DisplayType }; // [ShapeType]_[DisplayType], e.g. TermPart.Summary, TermPart.Detail. context.Shape.Metadata.Alternates.Add($"TermPart_{context.Shape.Metadata.DisplayType}"); @@ -143,7 +143,7 @@ public void Discover(ShapeTableBuilder builder) Level = level, Term = termShape, TermContentItem = termContentItem, - Terms = childTerms ?? Array.Empty(), + Terms = childTerms ?? [], TaxonomyContentItem = taxonomyContentItem })); @@ -181,7 +181,7 @@ public void Discover(ShapeTableBuilder builder) TaxonomyContentItem = taxonomyContentItem, TermContentItem = termContentItem, Term = termShape, - Terms = childTerms ?? Array.Empty() + Terms = childTerms ?? [] })); shape.Metadata.Differentiator = differentiator; @@ -246,9 +246,11 @@ public void Discover(ShapeTableBuilder builder) termItem.Metadata.Alternates.Add("TermContentItem__" + differentiator + "__" + encodedContentType + "__level__" + level); } }); + + return ValueTask.CompletedTask; } - private int FindTerm(JArray termsArray, string termContentItemId, int level, out ContentItem contentItem) + private static int FindTerm(JArray termsArray, string termContentItemId, int level, out ContentItem contentItem) { foreach (var term in termsArray.Cast()) { diff --git a/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantFeatureProfileShapeTableProvider.cs b/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantFeatureProfileShapeTableProvider.cs index 0225809a2ae..26a8bec69ee 100644 --- a/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantFeatureProfileShapeTableProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantFeatureProfileShapeTableProvider.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using OrchardCore.DisplayManagement; using OrchardCore.DisplayManagement.Descriptors; using OrchardCore.DisplayManagement.Views; @@ -7,9 +8,9 @@ namespace OrchardCore.Tenants.Services; [Feature("OrchardCore.Tenants.FeatureProfiles")] -public class TenantFeatureProfileShapeTableProvider : IShapeTableProvider +public class TenantFeatureProfileShapeTableProvider : ShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("TenantActionTags") .OnDisplaying(async displaying => @@ -19,5 +20,7 @@ public void Discover(ShapeTableBuilder builder) await displaying.Shape.AddAsync(new ShapeViewModel("ProfileFeatureTags", entry), "10"); } }); + + return ValueTask.CompletedTask; } } diff --git a/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantFeatureShapeTableProvider.cs b/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantFeatureShapeTableProvider.cs index 9903ff82259..36c02f92603 100644 --- a/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantFeatureShapeTableProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantFeatureShapeTableProvider.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using OrchardCore.DisplayManagement; using OrchardCore.DisplayManagement.Descriptors; using OrchardCore.DisplayManagement.Views; @@ -7,9 +8,9 @@ namespace OrchardCore.Tenants.Services; [RequireFeatures("OrchardCore.Features")] -public class TenantFeatureShapeTableProvider : IShapeTableProvider +public class TenantFeatureShapeTableProvider : ShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("TenantActionButtons") .OnDisplaying(async displaying => @@ -19,5 +20,7 @@ public void Discover(ShapeTableBuilder builder) await displaying.Shape.AddAsync(new ShapeViewModel("ManageFeaturesActionButton", entry), "10"); } }); + + return ValueTask.CompletedTask; } } diff --git a/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantShapeTableProvider.cs b/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantShapeTableProvider.cs index e400cb814a2..164c83e3cb7 100644 --- a/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantShapeTableProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.Tenants/Services/TenantShapeTableProvider.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using OrchardCore.DisplayManagement; using OrchardCore.DisplayManagement.Descriptors; using OrchardCore.DisplayManagement.Views; @@ -5,26 +6,28 @@ namespace OrchardCore.Tenants.Services; -public class TenantShapeTableProvider : IShapeTableProvider +public class TenantShapeTableProvider : ShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("TenantActionTags") - .OnDisplaying(async displaying => - { - if (displaying.Shape.TryGetProperty("ShellSettingsEntry", out ShellSettingsEntry entry)) + .OnDisplaying(async displaying => { - await displaying.Shape.AddAsync(new ShapeViewModel("ManageTenantActionTags", entry), "5"); - } - }); + if (displaying.Shape.TryGetProperty("ShellSettingsEntry", out ShellSettingsEntry entry)) + { + await displaying.Shape.AddAsync(new ShapeViewModel("ManageTenantActionTags", entry), "5"); + } + }); builder.Describe("TenantActionButtons") - .OnDisplaying(async displaying => - { - if (displaying.Shape.TryGetProperty("ShellSettingsEntry", out ShellSettingsEntry entry)) - { - await displaying.Shape.AddAsync(new ShapeViewModel("ManageTenantActionButtons", entry), "5"); - } - }); + .OnDisplaying(async displaying => + { + if (displaying.Shape.TryGetProperty("ShellSettingsEntry", out ShellSettingsEntry entry)) + { + await displaying.Shape.AddAsync(new ShapeViewModel("ManageTenantActionButtons", entry), "5"); + } + }); + + return ValueTask.CompletedTask; } } diff --git a/src/OrchardCore.Modules/OrchardCore.Users/UserMenuShapeTableProvider.cs b/src/OrchardCore.Modules/OrchardCore.Users/UserMenuShapeTableProvider.cs index aa8a5676c0a..d2874b33f52 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/UserMenuShapeTableProvider.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/UserMenuShapeTableProvider.cs @@ -1,10 +1,10 @@ -using System; +using System.Threading.Tasks; using OrchardCore.DisplayManagement.Descriptors; using OrchardCore.DisplayManagement.Utilities; namespace OrchardCore.Users; -public class UserMenuShapeTableProvider : IShapeTableProvider +public class UserMenuShapeTableProvider : ShapeTableProvider { private const string BaseShapeType = "UserMenuItems"; @@ -12,7 +12,7 @@ public class UserMenuShapeTableProvider : IShapeTableProvider private const string ShapeAlternatePrefix = $"{BaseShapeType}_"; - public void Discover(ShapeTableBuilder builder) + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { // Describe any shape-type that starts with 'UserMenuItems__'. builder.Describe($"{ShapeTypePrefix}*") @@ -32,5 +32,7 @@ public void Discover(ShapeTableBuilder builder) // 'UserMenuItems_{displaType}__{subType}' e.g. 'UserMenuItems-Dashboard.DetailAdmin.cshtml'. context.Shape.Metadata.Alternates.Add($"{ShapeAlternatePrefix}{context.Shape.Metadata.DisplayType}__{subType}"); }); + + return ValueTask.CompletedTask; } } diff --git a/src/OrchardCore.Modules/OrchardCore.Widgets/ContentCardShapes.cs b/src/OrchardCore.Modules/OrchardCore.Widgets/ContentCardShapes.cs index 699fef9163b..92344505c8d 100644 --- a/src/OrchardCore.Modules/OrchardCore.Widgets/ContentCardShapes.cs +++ b/src/OrchardCore.Modules/OrchardCore.Widgets/ContentCardShapes.cs @@ -1,9 +1,9 @@ -using System; +using System.Threading.Tasks; using OrchardCore.DisplayManagement.Descriptors; namespace OrchardCore.Widgets { - public class ContentCardShapes : IShapeTableProvider + public class ContentCardShapes : ShapeTableProvider { //Card Shape private const string ContentCardEdit = "ContentCard_Edit"; @@ -14,12 +14,12 @@ public class ContentCardShapes : IShapeTableProvider //Card Editor Fields private const string ContentCardFieldsEdit = "ContentCard_Fields_Edit"; - public void Discover(ShapeTableBuilder builder) + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { builder.Describe(ContentCardEdit) .OnDisplaying(context => { - //Defines Edit Alternates for the Content Item being edited. + // Defines Edit Alternates for the Content Item being edited. dynamic contentCardEditor = context.Shape; string collectionType = contentCardEditor.CollectionShapeType; string contentType = contentCardEditor.ContentTypeValue; @@ -27,48 +27,48 @@ public void Discover(ShapeTableBuilder builder) string namedPart = contentCardEditor.CollectionPartName; if (contentCardEditor.BuildEditor == true) { - //Define edit card shape per collection type - //ContentCard_Edit__[CollectionType] - //e.g. ContentCard_Edit__FlowPart, ContentCard_Edit__BagPart, ContentCard_Edit__WidgetsListPart + // Define edit card shape per collection type + // ContentCard_Edit__[CollectionType] + // e.g. ContentCard_Edit__FlowPart, ContentCard_Edit__BagPart, ContentCard_Edit__WidgetsListPart contentCardEditor.Metadata.Alternates.Add($"{ContentCardEdit}__{collectionType}"); - //Define edit card shape per content type + // Define edit card shape per content type // ContentCard_Edit__[ContentType] e.g. ContentCard_Edit__Paragraph, ContentCard_Edit__Form, ContentCard_Edit__Input contentCardEditor.Metadata.Alternates.Add($"{ContentCardEdit}__{contentType}"); - //Define edit card shape per content type per collection type - //ContentCard_Edit__[CollectionType]__[ContentType] - //e.g. ContentCard_Edit__FlowPart__Paragraph, ContentCard_Edit__BagPart__Form, ContentCard_Edit__FlowPart__Input + // Define edit card shape per content type per collection type + // ContentCard_Edit__[CollectionType]__[ContentType] + // e.g. ContentCard_Edit__FlowPart__Paragraph, ContentCard_Edit__BagPart__Form, ContentCard_Edit__FlowPart__Input contentCardEditor.Metadata.Alternates.Add($"{ContentCardEdit}__{collectionType}__{contentType}"); - //If we have Parent Content Type, + // If we have Parent Content Type, if (!string.IsNullOrWhiteSpace(parentContentType)) { - //Define edit card shape for all child in collection per parent content type - //ContentCard_Edit__[ParentContentType]__[CollectionType] - //e.g. ContentCard_Edit__Page__FlowPart, ContentCard_Edit__Form__FlowPart, ContentCard_Edit__Services__BagPart + // Define edit card shape for all child in collection per parent content type + // ContentCard_Edit__[ParentContentType]__[CollectionType] + // e.g. ContentCard_Edit__Page__FlowPart, ContentCard_Edit__Form__FlowPart, ContentCard_Edit__Services__BagPart contentCardEditor.Metadata.Alternates.Add($"{ContentCardEdit}__{parentContentType}__{collectionType}"); - //Define edit card shape for selected child with specific type per parent content type - //ContentCard_Edit__[ParentContentType]__[ContentType] - //e.g. ContentCard_Edit__Page__Form, ContentCard_Edit__Form__Label, ContentCard_Edit__LandingPage__Service + // Define edit card shape for selected child with specific type per parent content type + // ContentCard_Edit__[ParentContentType]__[ContentType] + // e.g. ContentCard_Edit__Page__Form, ContentCard_Edit__Form__Label, ContentCard_Edit__LandingPage__Service contentCardEditor.Metadata.Alternates.Add($"{ContentCardEdit}__{parentContentType}__{contentType}"); - //Define edit card shape for selected child with specific type per parent content type for given collection - //ContentCard_Edit__[ParentContentType]__[CollectionType]__[ContentType] e.g. ContentCard_Edit__LandingPage__FlowPart__Service, - //ContentCard_Edit__LandingPage__BagPart__Service, ContentCard_Edit__Form__FlowPart__Label + // Define edit card shape for selected child with specific type per parent content type for given collection + // ContentCard_Edit__[ParentContentType]__[CollectionType]__[ContentType] e.g. ContentCard_Edit__LandingPage__FlowPart__Service, + // ContentCard_Edit__LandingPage__BagPart__Service, ContentCard_Edit__Form__FlowPart__Label contentCardEditor.Metadata.Alternates.Add($"{ContentCardEdit}__{parentContentType}__{collectionType}__{contentType}"); if (!string.IsNullOrWhiteSpace(namedPart) && !(namedPart.Equals(collectionType))) { - //Define edit card shape for selected child with specific type and partname per parent content type - //ContentCard_Edit__[ParentContentType]__[PartName] - //e.g. ContentCard_Edit__Grid__LeftColumn, ContentCard_Edit__LandingPage__Services + // Define edit card shape for selected child with specific type and partname per parent content type + // ContentCard_Edit__[ParentContentType]__[PartName] + // e.g. ContentCard_Edit__Grid__LeftColumn, ContentCard_Edit__LandingPage__Services contentCardEditor.Metadata.Alternates.Add($"{ContentCardEdit}__{parentContentType}__{namedPart}"); - //Define edit card shape for selected child with specific type and partname per parent content type - //ContentCard_Edit__[ContentType]__[ContentType] - //e.g. ContentCard_Edit__Grid__LeftColumn__Client, ContentCard_Edit__LandingPage__Services__Service + // Define edit card shape for selected child with specific type and partname per parent content type + // ContentCard_Edit__[ContentType]__[ContentType] + // e.g. ContentCard_Edit__Grid__LeftColumn__Client, ContentCard_Edit__LandingPage__Services__Service contentCardEditor.Metadata.Alternates.Add($"{ContentCardEdit}__{parentContentType}__{namedPart}__{contentType}"); } } @@ -81,52 +81,52 @@ public void Discover(ShapeTableBuilder builder) // Alternates for Outer Frame of ContentCard dynamic contentCardFrame = context.Shape; string collectionType = contentCardFrame.ChildContent.CollectionShapeType; - string contentType = contentCardFrame.ChildContent.ContentTypeValue as string; + var contentType = contentCardFrame.ChildContent.ContentTypeValue as string; string parentContentType = contentCardFrame.ChildContent.ParentContentType; string namedPart = contentCardFrame.ChildContent.CollectionPartName; - //Define Frame card shape per collection type - //ContentCard_Frame__[CollectionType] - //e.g. ContentCard_Frame__FlowPart, ContentCard_Frame__BagPart, ContentCard_Frame__WidgetsListPart + // Define Frame card shape per collection type + // ContentCard_Frame__[CollectionType] + // e.g. ContentCard_Frame__FlowPart, ContentCard_Frame__BagPart, ContentCard_Frame__WidgetsListPart contentCardFrame.Metadata.Alternates.Add($"{ContentCardFrame}__{collectionType}"); - //Define Frame card shape per content type - //ContentCard_Frame__[ContentType] - //e.g. ContentCard_Frame__Paragraph, ContentCard_Frame__Form, ContentCard_Frame__Input + // Define Frame card shape per content type + // ContentCard_Frame__[ContentType] + // e.g. ContentCard_Frame__Paragraph, ContentCard_Frame__Form, ContentCard_Frame__Input contentCardFrame.Metadata.Alternates.Add($"{ContentCardFrame}__{contentType}"); - //Define Frame card shape per content type per collection type - //ContentCard_Frame__[CollectionType]__[ContentType] - //e.g. ContentCard_Frame__FlowPart__Paragraph, ContentCard_Frame__BagPart__Form, ContentCard_Frame__FlowPart__Input + // Define Frame card shape per content type per collection type + // ContentCard_Frame__[CollectionType]__[ContentType] + // e.g. ContentCard_Frame__FlowPart__Paragraph, ContentCard_Frame__BagPart__Form, ContentCard_Frame__FlowPart__Input contentCardFrame.Metadata.Alternates.Add($"{ContentCardFrame}__{collectionType}__{contentType}"); if (!string.IsNullOrWhiteSpace(parentContentType)) { - //Define frame card shape for children per parent content type for given collection - //ContentCard_Frame__[ParentContentType]__[CollectionType] - //e.g. ContentCard_Frame__Page__FlowPart, ContentCard_Frame__LandingPage__BagPart, ContentCard_Frame__Form__FlowPart + // Define frame card shape for children per parent content type for given collection + // ContentCard_Frame__[ParentContentType]__[CollectionType] + // e.g. ContentCard_Frame__Page__FlowPart, ContentCard_Frame__LandingPage__BagPart, ContentCard_Frame__Form__FlowPart contentCardFrame.Metadata.Alternates.Add($"{ContentCardFrame}__{parentContentType}__{collectionType}"); - //Define frame card shape for child with specific type per parent content type - //ContentCard_Frame__[ParentContentType]__[ContentType] - //e.g. ContentCard_Frame__Page__Form, ContentCard_Frame__Form__Label + // Define frame card shape for child with specific type per parent content type + // ContentCard_Frame__[ParentContentType]__[ContentType] + // e.g. ContentCard_Frame__Page__Form, ContentCard_Frame__Form__Label contentCardFrame.Metadata.Alternates.Add($"{ContentCardFrame}__{parentContentType}__{contentType}"); - //Define edit frame shape for selected child with specific type per parent content type for given collection - //ContentCard_Frame__[ParentContentType]__[CollectionType]__[ContentType] - //e.g. ContentCard_Frame__Page__FlowPart__Container, ContentCard_Frame__LandingPage__BagPart__Service, ContentCard_Frame__Form__FlowPart__Label + // Define edit frame shape for selected child with specific type per parent content type for given collection + // ContentCard_Frame__[ParentContentType]__[CollectionType]__[ContentType] + // e.g. ContentCard_Frame__Page__FlowPart__Container, ContentCard_Frame__LandingPage__BagPart__Service, ContentCard_Frame__Form__FlowPart__Label contentCardFrame.Metadata.Alternates.Add($"{ContentCardFrame}__{parentContentType}__{collectionType}__{contentType}"); if (!string.IsNullOrWhiteSpace(namedPart) && !namedPart.Equals(collectionType)) { - //Define frame card shape for child with specific partname and parent content type - //ContentCard_Frame__[ParentContentType]__[PartName] - //e.g. ContentCard_Frame__Grid__LeftColumn, ContentCard_Frame__LandingPage__Services + // Define frame card shape for child with specific partname and parent content type + // ContentCard_Frame__[ParentContentType]__[PartName] + // e.g. ContentCard_Frame__Grid__LeftColumn, ContentCard_Frame__LandingPage__Services contentCardFrame.Metadata.Alternates.Add($"{ContentCardFrame}__{parentContentType}__{namedPart}"); - //Define edit card shape for selected child with specific type per parent content type - //ContentCard_Frame__[ParentContentType]__[NamedPart]__[ContentType] - //e.g. ContentCard_Frame__Grid__LeftColumn__Client, ContentCard_Frame__LandingPage__Clients__Client + // Define edit card shape for selected child with specific type per parent content type + // ContentCard_Frame__[ParentContentType]__[NamedPart]__[ContentType] + // e.g. ContentCard_Frame__Grid__LeftColumn__Client, ContentCard_Frame__LandingPage__Clients__Client contentCardFrame.Metadata.Alternates.Add($"{ContentCardFrame}__{parentContentType}__{namedPart}__{contentType}"); } } @@ -136,9 +136,11 @@ public void Discover(ShapeTableBuilder builder) .OnDisplaying(context => { dynamic contentCardEditorFields = context.Shape; - string collectionType = contentCardEditorFields.CardShape.CollectionShapeType as string; + var collectionType = contentCardEditorFields.CardShape.CollectionShapeType as string; contentCardEditorFields.Metadata.Alternates.Add($"{collectionType}_Fields_Edit"); }); + + return ValueTask.CompletedTask; } } } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/DefaultShapeTableManager.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/DefaultShapeTableManager.cs index bfb4a55dbb4..05f07e0d972 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/DefaultShapeTableManager.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/DefaultShapeTableManager.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -48,15 +49,15 @@ public DefaultShapeTableManager( } public ShapeTable GetShapeTable(string themeId) + => GetShapeTableAsync(themeId).GetAwaiter().GetResult(); + + public async Task GetShapeTableAsync(string themeId) { var cacheKey = $"ShapeTable:{themeId}"; if (!_memoryCache.TryGetValue(cacheKey, out ShapeTable shapeTable)) { - if (_logger.IsEnabled(LogLevel.Information)) - { - _logger.LogInformation("Start building shape table"); - } + _logger.LogInformation("Start building shape table"); HashSet excludedFeatures; @@ -73,7 +74,7 @@ public ShapeTable GetShapeTable(string themeId) var strategyFeature = _typeFeatureProvider.GetFeatureForDependency(bindingStrategy.GetType()); var builder = new ShapeTableBuilder(strategyFeature, excludedFeatures); - bindingStrategy.Discover(builder); + await bindingStrategy.DiscoverAsync(builder); var builtAlterations = builder.BuildAlterations(); BuildDescriptors(bindingStrategy, builtAlterations, shapeDescriptors); @@ -88,10 +89,7 @@ public ShapeTable GetShapeTable(string themeId) } } - var enabledAndOrderedFeatureIds = _shellFeaturesManager - .GetEnabledFeaturesAsync() - .GetAwaiter() - .GetResult() + var enabledAndOrderedFeatureIds = (await _shellFeaturesManager.GetEnabledFeaturesAsync()) .Select(f => f.Id) .ToList(); @@ -120,10 +118,7 @@ public ShapeTable GetShapeTable(string themeId) bindings: descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase) ); - if (_logger.IsEnabled(LogLevel.Information)) - { - _logger.LogInformation("Done building shape table"); - } + _logger.LogInformation("Done building shape table"); _memoryCache.Set(cacheKey, shapeTable, new MemoryCacheEntryOptions { Priority = CacheItemPriority.NeverRemove }); } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/IShapeTableManager.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/IShapeTableManager.cs index 1e5e4b852b1..72683e8ff6d 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/IShapeTableManager.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/IShapeTableManager.cs @@ -1,6 +1,12 @@ +using System; +using System.Threading.Tasks; + namespace OrchardCore.DisplayManagement.Descriptors; public interface IShapeTableManager { + [Obsolete($"Instead, utilize the {nameof(GetShapeTableAsync)} method. This current method is slated for removal in upcoming releases.")] ShapeTable GetShapeTable(string themeId); + + Task GetShapeTableAsync(string themeId); } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/IShapeTableProvider.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/IShapeTableProvider.cs index 86ecf2c4561..1b9bddd6f7c 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/IShapeTableProvider.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/IShapeTableProvider.cs @@ -1,6 +1,19 @@ +using System; +using System.Threading.Tasks; + namespace OrchardCore.DisplayManagement.Descriptors; public interface IShapeTableProvider { + [Obsolete($"Instead, utilize the {nameof(DiscoverAsync)} method. This current method is slated for removal in upcoming releases.")] void Discover(ShapeTableBuilder builder); + + ValueTask DiscoverAsync(ShapeTableBuilder builder) + { +#pragma warning disable CS0618 // Type or member is obsolete + Discover(builder); +#pragma warning restore CS0618 // Type or member is obsolete + + return ValueTask.CompletedTask; + } } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeAttributeStrategy/ShapeAttributeBindingStrategy.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeAttributeStrategy/ShapeAttributeBindingStrategy.cs index d2a2f6719e1..c225ab353f9 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeAttributeStrategy/ShapeAttributeBindingStrategy.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeAttributeStrategy/ShapeAttributeBindingStrategy.cs @@ -16,7 +16,7 @@ namespace OrchardCore.DisplayManagement.Descriptors.ShapeAttributeStrategy { - public class ShapeAttributeBindingStrategy : IShapeTableHarvester + public class ShapeAttributeBindingStrategy : ShapeTableProvider, IShapeTableHarvester { private readonly ITypeFeatureProvider _typeFeatureProvider; private readonly IEnumerable _shapeProviders; @@ -29,7 +29,7 @@ public ShapeAttributeBindingStrategy( _shapeProviders = shapeProviders; } - public void Discover(ShapeTableBuilder builder) + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { var shapeAttributeOccurrences = new List(); @@ -57,6 +57,8 @@ public void Discover(ShapeTableBuilder builder) occurrence.MethodInfo.DeclaringType.FullName + "::" + occurrence.MethodInfo.Name, CreateDelegate(occurrence)); } + + return ValueTask.CompletedTask; } [DebuggerStepThrough] diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs index b667b1e140d..99862f3a9e2 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.Hosting; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -15,7 +16,7 @@ namespace OrchardCore.DisplayManagement.Descriptors.ShapePlacementStrategy /// /// This component discovers and announces the shape alterations implied by the contents of the Placement.json files /// - public class ShapePlacementParsingStrategy : IShapeTableHarvester + public class ShapePlacementParsingStrategy : ShapeTableProvider, IShapeTableHarvester { private readonly IHostEnvironment _hostingEnvironment; private readonly IShellFeaturesManager _shellFeaturesManager; @@ -31,18 +32,18 @@ public ShapePlacementParsingStrategy( _placementParseMatchProviders = placementParseMatchProviders; } - public void Discover(ShapeTableBuilder builder) + public override async ValueTask DiscoverAsync(ShapeTableBuilder builder) { - var enabledFeatures = _shellFeaturesManager.GetEnabledFeaturesAsync().GetAwaiter().GetResult() + var enabledFeatures = (await _shellFeaturesManager.GetEnabledFeaturesAsync()) .Where(Feature => !builder.ExcludedFeatureIds.Contains(Feature.Id)); foreach (var featureDescriptor in enabledFeatures) { - ProcessFeatureDescriptor(builder, featureDescriptor); + await ProcessFeatureDescriptorAsync(builder, featureDescriptor); } } - private void ProcessFeatureDescriptor(ShapeTableBuilder builder, IFeatureInfo featureDescriptor) + private async Task ProcessFeatureDescriptorAsync(ShapeTableBuilder builder, IFeatureInfo featureDescriptor) { // TODO : (ngm) Replace with configuration Provider and read from that. // Dont use JSON Deserializer directly. @@ -51,9 +52,9 @@ private void ProcessFeatureDescriptor(ShapeTableBuilder builder, IFeatureInfo fe if (virtualFileInfo.Exists) { - using var stream = virtualFileInfo.CreateReadStream(); + await using var stream = virtualFileInfo.CreateReadStream(); using var reader = new StreamReader(stream); - using var jtr = new JsonTextReader(reader); + await using var jtr = new JsonTextReader(reader); var serializer = new JsonSerializer(); var placementFile = serializer.Deserialize(jtr); @@ -76,7 +77,7 @@ private void ProcessPlacementFile(ShapeTableBuilder builder, IFeatureInfo featur Func predicate = ctx => CheckFilter(ctx, filter); - if (matches.Any()) + if (matches.Count > 0) { predicate = matches.Aggregate(predicate, BuildPredicate); } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeTablePlacementProvider.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeTablePlacementProvider.cs index fd2dab2ddea..e11a2ee0ed0 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeTablePlacementProvider.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeTablePlacementProvider.cs @@ -28,7 +28,7 @@ public async Task BuildPlacementInfoResolverAsync(IBuild return null; } - var shapeTable = _shapeTableManager.GetShapeTable(theme.Id); + var shapeTable = await _shapeTableManager.GetShapeTableAsync(theme.Id); return new ShapeTablePlacementResolver(shapeTable); } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeTableProvider.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeTableProvider.cs new file mode 100644 index 00000000000..057df85a480 --- /dev/null +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeTableProvider.cs @@ -0,0 +1,14 @@ +using System; +using System.Threading.Tasks; + +namespace OrchardCore.DisplayManagement.Descriptors; + +public abstract class ShapeTableProvider : IShapeTableProvider +{ + [Obsolete($"Instead, utilize the {nameof(IShapeTableProvider.DiscoverAsync)} method. This current method is slated for removal in upcoming releases.")] + public void Discover(ShapeTableBuilder builder) + { + } + + public abstract ValueTask DiscoverAsync(ShapeTableBuilder builder); +} diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeTemplateStrategy/ShapeTemplateBindingStrategy.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeTemplateStrategy/ShapeTemplateBindingStrategy.cs index 8902665faaf..4631ccb56b4 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeTemplateStrategy/ShapeTemplateBindingStrategy.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Descriptors/ShapeTemplateStrategy/ShapeTemplateBindingStrategy.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using OrchardCore.Environment.Extensions; @@ -12,7 +13,7 @@ namespace OrchardCore.DisplayManagement.Descriptors.ShapeTemplateStrategy { - public class ShapeTemplateBindingStrategy : IShapeTableHarvester + public class ShapeTemplateBindingStrategy : ShapeTableProvider, IShapeTableHarvester { private readonly IEnumerable _harvesters; private readonly IEnumerable _shapeTemplateViewEngines; @@ -38,32 +39,27 @@ public ShapeTemplateBindingStrategy( public bool DisableMonitoring { get; set; } - private static IEnumerable Once(IEnumerable featureDescriptors) + public override async ValueTask DiscoverAsync(ShapeTableBuilder builder) { - var once = new ConcurrentDictionary(); - return featureDescriptors.Select(x => x.Extension).Where(ed => once.TryAdd(ed.Id, null)).ToList(); - } - - public void Discover(ShapeTableBuilder builder) - { - if (_logger.IsEnabled(LogLevel.Information)) - { - _logger.LogInformation("Start discovering shapes"); - } + _logger.LogInformation("Start discovering shapes"); var harvesterInfos = _harvesters - .Select(harvester => new { harvester, subPaths = harvester.SubPaths() }) + .Select(harvester => new + { + harvester, + subPaths = harvester.SubPaths() + }) .ToList(); - var enabledFeatures = _shellFeaturesManager.GetEnabledFeaturesAsync().GetAwaiter().GetResult(); - var enabledFeatureIds = enabledFeatures.Select(f => f.Id).ToArray(); + var enabledFeatures = await _shellFeaturesManager.GetEnabledFeaturesAsync(); + var enabledFeatureIds = enabledFeatures.Select(f => f.Id).ToList(); // Excludes the extensions whose templates are already associated to an excluded feature that is still enabled. var activeExtensions = Once(enabledFeatures) .Where(e => !e.Features.Any(f => builder.ExcludedFeatureIds.Contains(f.Id) && enabledFeatureIds.Contains(f.Id))) .ToArray(); - if (!_viewEnginesByExtension.Any()) + if (_viewEnginesByExtension.Count == 0) { foreach (var viewEngine in _shapeTemplateViewEngines) { @@ -79,26 +75,20 @@ public void Discover(ShapeTableBuilder builder) var hits = activeExtensions.Select(extensionDescriptor => { - if (_logger.IsEnabled(LogLevel.Information)) - { - _logger.LogInformation("Start discovering candidate views filenames"); - } + _logger.LogInformation("Start discovering candidate views filenames"); var pathContexts = harvesterInfos.SelectMany(harvesterInfo => harvesterInfo.subPaths.Select(subPath => { var filePaths = _fileProviderAccessor.FileProvider.GetViewFilePaths( PathExtensions.Combine(extensionDescriptor.SubPath, subPath), - _viewEnginesByExtension.Keys.ToArray(), + [.. _viewEnginesByExtension.Keys], inViewsFolder: true, inDepth: false).ToArray(); return new { harvesterInfo.harvester, subPath, filePaths }; })) .ToList(); - if (_logger.IsEnabled(LogLevel.Information)) - { - _logger.LogInformation("Done discovering candidate views filenames"); - } + _logger.LogInformation("Done discovering candidate views filenames"); var fileContexts = pathContexts.SelectMany(pathContext => _shapeTemplateViewEngines.SelectMany(ve => { @@ -157,10 +147,13 @@ public void Discover(ShapeTableBuilder builder) }); } - if (_logger.IsEnabled(LogLevel.Information)) - { - _logger.LogInformation("Done discovering shapes"); - } + _logger.LogInformation("Done discovering shapes"); + } + + private static IEnumerable Once(IEnumerable featureDescriptors) + { + var once = new ConcurrentDictionary(); + return featureDescriptors.Select(x => x.Extension).Where(ed => once.TryAdd(ed.Id, null)).ToList(); } } } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs index 915ff902d03..fab1d676f32 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs @@ -78,7 +78,7 @@ public async Task ExecuteAsync(DisplayContext context) try { var theme = await _themeManager.GetThemeAsync(); - var shapeTable = _shapeTableManager.GetShapeTable(theme?.Id); + var shapeTable = await _shapeTableManager.GetShapeTableAsync(theme?.Id); // Evaluate global Shape Display Events. await _shapeDisplayEvents.InvokeAsync((e, displayContext) => e.DisplayingAsync(displayContext), displayContext, _logger); diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultShapeFactory.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultShapeFactory.cs index 3844afb4398..c3104a48e92 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultShapeFactory.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultShapeFactory.cs @@ -53,7 +53,7 @@ private async Task GetShapeTableAsync() if (_scopedShapeTable == null) { var theme = await _themeManager.GetThemeAsync(); - _scopedShapeTable = _shapeTableManager.GetShapeTable(theme?.Id); + _scopedShapeTable = await _shapeTableManager.GetShapeTableAsync(theme?.Id); } return _scopedShapeTable; diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Shapes/CoreShapes.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Shapes/CoreShapes.cs index 13f99765a12..070b1594679 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Shapes/CoreShapes.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Shapes/CoreShapes.cs @@ -119,9 +119,9 @@ public IHtmlContent Message(IShape Shape) } } - public class CoreShapesTableProvider : IShapeTableProvider + public class CoreShapesTableProvider : ShapeTableProvider { - public void Discover(ShapeTableBuilder builder) + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { builder.Describe("List") .OnCreated(created => @@ -133,6 +133,8 @@ public void Discover(ShapeTableBuilder builder) list.ItemClasses = new List(); list.ItemAttributes = new Dictionary(); }); + + return ValueTask.CompletedTask; } } } diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Zones/ZoneShapeAlternates.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Zones/ZoneShapeAlternates.cs index 032f90c48d0..04442228b03 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Zones/ZoneShapeAlternates.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Zones/ZoneShapeAlternates.cs @@ -1,19 +1,21 @@ +using System.Threading.Tasks; using OrchardCore.DisplayManagement.Descriptors; -namespace OrchardCore.DisplayManagement.Zones +namespace OrchardCore.DisplayManagement.Zones; + +public class ZoneShapeAlternates : ShapeTableProvider { - public class ZoneShapeAlternates : IShapeTableProvider + public override ValueTask DiscoverAsync(ShapeTableBuilder builder) { - public void Discover(ShapeTableBuilder builder) - { - builder.Describe("Zone") - .OnDisplaying(context => + builder.Describe("Zone") + .OnDisplaying(context => + { + if (context.Shape.TryGetProperty("ZoneName", out string zoneName)) { - if (context.Shape.TryGetProperty("ZoneName", out string zoneName)) - { - context.Shape.Metadata.Alternates.Add("Zone__" + zoneName); - } - }); - } + context.Shape.Metadata.Alternates.Add("Zone__" + zoneName); + } + }); + + return ValueTask.CompletedTask; } } diff --git a/test/OrchardCore.Tests/DisplayManagement/Decriptors/DefaultShapeTableManagerTests.cs b/test/OrchardCore.Tests/DisplayManagement/Decriptors/DefaultShapeTableManagerTests.cs index 58d5b0dfdb1..22bfe3f84f4 100644 --- a/test/OrchardCore.Tests/DisplayManagement/Decriptors/DefaultShapeTableManagerTests.cs +++ b/test/OrchardCore.Tests/DisplayManagement/Decriptors/DefaultShapeTableManagerTests.cs @@ -308,17 +308,17 @@ public void ManagerCanBeResolved() } [Fact] - public void DefaultShapeTableIsReturnedForNullOrEmpty() + public async Task DefaultShapeTableIsReturnedForNullOrEmpty() { var manager = _serviceProvider.GetService(); - var shapeTable1 = manager.GetShapeTable(null); - var shapeTable2 = manager.GetShapeTable(string.Empty); + var shapeTable1 = await manager.GetShapeTableAsync(null); + var shapeTable2 = await manager.GetShapeTableAsync(string.Empty); Assert.NotNull(shapeTable1.Descriptors["Hello"]); Assert.NotNull(shapeTable2.Descriptors["Hello"]); } [Fact] - public void CallbackAlterationsContributeToDescriptor() + public async Task CallbackAlterationsContributeToDescriptor() { Func cb1 = x => { return Task.CompletedTask; }; Func cb2 = x => { return Task.CompletedTask; }; @@ -334,26 +334,27 @@ public void CallbackAlterationsContributeToDescriptor() var manager = _serviceProvider.GetService(); - var foo = manager.GetShapeTable(null).Descriptors["Foo"]; + var foo = (await manager.GetShapeTableAsync(null)).Descriptors["Foo"]; Assert.Same(cb1, foo.CreatingAsync.Single()); Assert.Same(cb2, foo.CreatedAsync.Single()); Assert.Same(cb3, foo.DisplayingAsync.Single()); Assert.Same(cb4, foo.DisplayedAsync.Single()); } + [Fact] - public void DefaultPlacementIsReturnedByDefault() + public async Task DefaultPlacementIsReturnedByDefault() { var manager = _serviceProvider.GetService(); - var hello = manager.GetShapeTable(null).Descriptors["Hello"]; + var hello = (await manager.GetShapeTableAsync(null)).Descriptors["Hello"]; hello.DefaultPlacement = "Header:5"; var result = hello.Placement(null); Assert.Equal("Header:5", result.Location); } [Fact] - public void DescribedPlacementIsReturnedIfNotNull() + public async Task DescribedPlacementIsReturnedIfNotNull() { var shapeDetail = new ShapePlacementContext("Foo", "Detail", string.Empty, null); var shapeSummary = new ShapePlacementContext("Foo", "Summary", string.Empty, null); @@ -365,7 +366,7 @@ public void DescribedPlacementIsReturnedIfNotNull() .Placement(ctx => ctx.DisplayType == "Summary" ? new PlacementInfo { Location = string.Empty } : null); var manager = _serviceProvider.GetService(); - var hello = manager.GetShapeTable(null).Descriptors["Hello1"]; + var hello = (await manager.GetShapeTableAsync(null)).Descriptors["Hello1"]; var result1 = hello.Placement(shapeDetail); var result2 = hello.Placement(shapeSummary); var result3 = hello.Placement(shapeTitle); @@ -383,7 +384,7 @@ public void DescribedPlacementIsReturnedIfNotNull() } [Fact] - public void TwoArgumentVariationDoesSameThing() + public async Task TwoArgumentVariationDoesSameThing() { var shapeDetail = new ShapePlacementContext("Foo", "Detail", string.Empty, null); var shapeSummary = new ShapePlacementContext("Foo", "Summary", string.Empty, null); @@ -395,7 +396,7 @@ public void TwoArgumentVariationDoesSameThing() .Placement(ctx => ctx.DisplayType == "Summary", new PlacementInfo { Location = string.Empty }); var manager = _serviceProvider.GetService(); - var hello = manager.GetShapeTable(null).Descriptors["Hello2"]; + var hello = (await manager.GetShapeTableAsync(null)).Descriptors["Hello2"]; var result1 = hello.Placement(shapeDetail); var result2 = hello.Placement(shapeSummary); var result3 = hello.Placement(shapeTitle); @@ -414,7 +415,7 @@ public void TwoArgumentVariationDoesSameThing() // "Path not supported yet" [Fact] - internal void PathConstraintShouldMatch() + internal async Task PathConstraintShouldMatch() { // all path have a trailing / as per the current implementation // todo: (sebros) find a way to 'use' the current implementation in DefaultContentDisplay.BindPlacement instead of emulating it @@ -442,7 +443,7 @@ internal void PathConstraintShouldMatch() .Placement(ctx => true, new PlacementInfo { Location = "Match" }); var manager = _serviceProvider.GetService(); - var hello = manager.GetShapeTable(null).Descriptors["Hello"]; + var hello = (await manager.GetShapeTableAsync(null)).Descriptors["Hello"]; //var result = hello.Placement(new ShapePlacementContext { Path = context }); //if (match) @@ -457,33 +458,33 @@ internal void PathConstraintShouldMatch() } [Fact] - public void OnlyShapesFromTheGivenThemeAreProvided() + public async Task OnlyShapesFromTheGivenThemeAreProvided() { _serviceProvider.GetService(); var manager = _serviceProvider.GetService(); - var table = manager.GetShapeTable("Theme1"); + var table = await manager.GetShapeTableAsync("Theme1"); Assert.True(table.Descriptors.ContainsKey("Theme1Shape")); Assert.False(table.Descriptors.ContainsKey("DerivedShape")); Assert.False(table.Descriptors.ContainsKey("BaseShape")); } [Fact] - public void ShapesFromTheBaseThemeAreProvided() + public async Task ShapesFromTheBaseThemeAreProvided() { _serviceProvider.GetService(); var manager = _serviceProvider.GetService(); - var table = manager.GetShapeTable("DerivedTheme"); + var table = await manager.GetShapeTableAsync("DerivedTheme"); Assert.False(table.Descriptors.ContainsKey("Theme1Shape")); Assert.True(table.Descriptors.ContainsKey("DerivedShape")); Assert.True(table.Descriptors.ContainsKey("BaseShape")); } [Fact] - public void DerivedThemesCanOverrideBaseThemeShapeBindings() + public async Task DerivedThemesCanOverrideBaseThemeShapeBindings() { _serviceProvider.GetService(); var manager = _serviceProvider.GetService(); - var table = manager.GetShapeTable("DerivedTheme"); + var table = await manager.GetShapeTableAsync("DerivedTheme"); Assert.True(table.Bindings.TryGetValue("OverriddenShape", out _)); Assert.Equal("DerivedTheme", table.Descriptors["OverriddenShape"].BindingSource); } diff --git a/test/OrchardCore.Tests/Stubs/TestShapeTableManager.cs b/test/OrchardCore.Tests/Stubs/TestShapeTableManager.cs index 99e6a002cda..eff29a99c76 100644 --- a/test/OrchardCore.Tests/Stubs/TestShapeTableManager.cs +++ b/test/OrchardCore.Tests/Stubs/TestShapeTableManager.cs @@ -2,33 +2,25 @@ using OrchardCore.DisplayManagement.Theming; using OrchardCore.Environment.Extensions; -namespace OrchardCore.Tests.Stubs +namespace OrchardCore.Tests.Stubs; + +public class TestShapeTableManager(ShapeTable defaultShapeTable) : IShapeTableManager { - public class TestShapeTableManager : IShapeTableManager - { - private readonly ShapeTable _defaultShapeTable; + private readonly ShapeTable _defaultShapeTable = defaultShapeTable; - public TestShapeTableManager(ShapeTable defaultShapeTable) - { - _defaultShapeTable = defaultShapeTable; - } + public ShapeTable GetShapeTable(string themeId) + => _defaultShapeTable; - public ShapeTable GetShapeTable(string themeId) - { - return _defaultShapeTable; - } - } + public Task GetShapeTableAsync(string themeId) + => Task.FromResult(_defaultShapeTable); +} + +public class MockThemeManager(IExtensionInfo des) : IThemeManager +{ + private readonly IExtensionInfo _dec = des; - public class MockThemeManager : IThemeManager + public Task GetThemeAsync() { - private readonly IExtensionInfo _dec; - public MockThemeManager(IExtensionInfo des) - { - _dec = des; - } - public Task GetThemeAsync() - { - return Task.FromResult(_dec); - } + return Task.FromResult(_dec); } }