diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/ContentTypeSettingsDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/ContentTypeSettingsDisplayDriver.cs index 59b19eafbed..29a3ddc0fee 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/ContentTypeSettingsDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/ContentTypeSettingsDisplayDriver.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Options; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentManagement.Metadata.Settings; using OrchardCore.ContentTypes.ViewModels; @@ -10,16 +11,22 @@ namespace OrchardCore.ContentTypes.Editors { public class ContentTypeSettingsDisplayDriver : ContentTypeDefinitionDisplayDriver { + private static readonly ContentTypeDefinitionDriverOptions _defaultOptions = new(); + + private readonly ContentTypeDefinitionOptions _options; + protected readonly IStringLocalizer S; - public ContentTypeSettingsDisplayDriver(IStringLocalizer stringLocalizer) + public ContentTypeSettingsDisplayDriver( + IStringLocalizer stringLocalizer, + IOptions options) { S = stringLocalizer; + _options = options.Value; } public override IDisplayResult Edit(ContentTypeDefinition contentTypeDefinition) - { - return Initialize("ContentTypeSettings_Edit", model => + => Initialize("ContentTypeSettings_Edit", model => { var settings = contentTypeDefinition.GetSettings(); @@ -30,8 +37,8 @@ public override IDisplayResult Edit(ContentTypeDefinition contentTypeDefinition) model.Securable = settings.Securable; model.Stereotype = settings.Stereotype; model.Description = settings.Description; + model.Options = GetOptions(contentTypeDefinition, settings.Stereotype); }).Location("Content:5"); - } public override async Task UpdateAsync(ContentTypeDefinition contentTypeDefinition, UpdateTypeEditorContext context) { @@ -39,25 +46,63 @@ public override async Task UpdateAsync(ContentTypeDefinition con if (await context.Updater.TryUpdateModelAsync(model, Prefix)) { - context.Builder.Creatable(model.Creatable); - context.Builder.Listable(model.Listable); - context.Builder.Draftable(model.Draftable); - context.Builder.Versionable(model.Versionable); - context.Builder.Securable(model.Securable); - context.Builder.WithDescription(model.Description); - var stereotype = model.Stereotype?.Trim(); + context.Builder.WithDescription(model.Description); context.Builder.Stereotype(stereotype); if (!IsAlphaNumericOrEmpty(stereotype)) { context.Updater.ModelState.AddModelError(nameof(ContentTypeSettingsViewModel.Stereotype), S["The stereotype should be alphanumeric."]); } + + var options = GetOptions(contentTypeDefinition, stereotype); + + Apply(context, model, options); } return Edit(contentTypeDefinition); } + private static void Apply(UpdateTypeEditorContext context, ContentTypeSettingsViewModel model, ContentTypeDefinitionDriverOptions options) + { + if (options.ShowVersionable) + { + context.Builder.Versionable(model.Versionable); + } + + if (options.ShowCreatable) + { + context.Builder.Creatable(model.Creatable); + } + + if (options.ShowSecurable) + { + context.Builder.Securable(model.Securable); + } + + if (options.ShowListable) + { + context.Builder.Listable(model.Listable); + } + } + + private ContentTypeDefinitionDriverOptions GetOptions(ContentTypeDefinition contentTypeDefinition, string stereotype) + { + if (contentTypeDefinition.Name != null + && _options.ContentTypes.TryGetValue(contentTypeDefinition.Name, out var typeOptions)) + { + return typeOptions; + } + + if (stereotype != null + && _options.Stereotypes.TryGetValue(stereotype, out var stereotypesOptions)) + { + return stereotypesOptions; + } + + return _defaultOptions; + } + private static bool IsAlphaNumericOrEmpty(string value) { if (string.IsNullOrEmpty(value)) diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewModels/ContentTypeSettingsViewModel.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewModels/ContentTypeSettingsViewModel.cs index 3d6d146be45..3081711a4d7 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewModels/ContentTypeSettingsViewModel.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/ViewModels/ContentTypeSettingsViewModel.cs @@ -1,13 +1,25 @@ +using Microsoft.AspNetCore.Mvc.ModelBinding; +using OrchardCore.ContentManagement.Metadata.Models; + namespace OrchardCore.ContentTypes.ViewModels { public class ContentTypeSettingsViewModel { public bool Creatable { get; set; } + public bool Listable { get; set; } + public bool Draftable { get; set; } + public bool Versionable { get; set; } + public bool Securable { get; set; } + public string Stereotype { get; set; } + public string Description { get; set; } + + [BindNever] + public ContentTypeDefinitionDriverOptions Options { get; set; } } } diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/ContentTypeSettings.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/ContentTypeSettings.Edit.cshtml index 969f695fa29..e79dab08f65 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/ContentTypeSettings.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Views/ContentTypeSettings.Edit.cshtml @@ -8,45 +8,60 @@ @T["(Optional) Description of the content type"] -
-
- - - @T["Determines if an instance of this content type can be created through the UI."] +@if (Model.Options.ShowCreatable) +{ +
+
+ + + @T["Determines if an instance of this content type can be created through the UI."] +
-
+} -
-
- - - @T["Determines if an instance of this content type can be listed through the UI."] +@if (Model.Options.ShowListable) +{ +
+
+ + + @T["Determines if an instance of this content type can be listed through the UI."] +
-
+} -
-
- - - @T["Determines if this content type supports draft versions."] +@if (Model.Options.ShowDraftable) +{ +
+
+ + + @T["Determines if this content type supports draft versions."] +
-
+} -
-
- - - @T["Determines if this content type supports versioning."] +@if (Model.Options.ShowVersionable) +{ +
+
+ + + @T["Determines if this content type supports versioning."] +
-
+} -
-
- - - @T["Determines if this content type can have custom permissions."] +@if (Model.Options.ShowSecurable) +{ +
+
+ + + @T["Determines if this content type can have custom permissions."] +
-
+}
diff --git a/src/OrchardCore.Modules/OrchardCore.CustomSettings/Startup.cs b/src/OrchardCore.Modules/OrchardCore.CustomSettings/Startup.cs index df5eeaf294f..7aa3c175c99 100644 --- a/src/OrchardCore.Modules/OrchardCore.CustomSettings/Startup.cs +++ b/src/OrchardCore.Modules/OrchardCore.CustomSettings/Startup.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; +using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.CustomSettings.Deployment; using OrchardCore.CustomSettings.Drivers; using OrchardCore.CustomSettings.Recipes; @@ -27,6 +28,17 @@ public override void ConfigureServices(IServiceCollection services) services.AddScoped(); services.AddRecipeExecutionStep(); + + services.Configure(options => + { + options.Stereotypes.TryAdd("CustomSettings", new ContentTypeDefinitionDriverOptions + { + ShowCreatable = false, + ShowListable = false, + ShowDraftable = false, + ShowVersionable = false, + }); + }); } } diff --git a/src/OrchardCore.Modules/OrchardCore.Users/Startup.cs b/src/OrchardCore.Modules/OrchardCore.Users/Startup.cs index dcaff32d83a..393c5bf417f 100644 --- a/src/OrchardCore.Modules/OrchardCore.Users/Startup.cs +++ b/src/OrchardCore.Modules/OrchardCore.Users/Startup.cs @@ -14,6 +14,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; using OrchardCore.Admin.Models; +using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.Data; using OrchardCore.Data.Migration; using OrchardCore.Deployment; @@ -459,6 +460,17 @@ public override void ConfigureServices(IServiceCollection services) services.AddScoped, CustomUserSettingsDisplayDriver>(); services.AddScoped(); services.AddDeployment(); + + services.Configure(options => + { + options.Stereotypes.TryAdd("CustomUserSettings", new ContentTypeDefinitionDriverOptions + { + ShowCreatable = false, + ShowListable = false, + ShowDraftable = false, + ShowVersionable = false, + }); + }); } } diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Models/ContentTypeDefinitionDriverOptions.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Models/ContentTypeDefinitionDriverOptions.cs new file mode 100644 index 00000000000..948b5b879b6 --- /dev/null +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Models/ContentTypeDefinitionDriverOptions.cs @@ -0,0 +1,14 @@ +namespace OrchardCore.ContentManagement.Metadata.Models; + +public class ContentTypeDefinitionDriverOptions +{ + public bool ShowCreatable { get; set; } + + public bool ShowListable { get; set; } + + public bool ShowDraftable { get; set; } + + public bool ShowVersionable { get; set; } + + public bool ShowSecurable { get; set; } +} diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Models/ContentTypeDefinitionOptions.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Models/ContentTypeDefinitionOptions.cs new file mode 100644 index 00000000000..31d2dd0d545 --- /dev/null +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Models/ContentTypeDefinitionOptions.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; + +namespace OrchardCore.ContentManagement.Metadata.Models; + +/// +/// Offers a method for configuring content type definitions to either display or conceal global settings from appearing on the UI. +/// +public class ContentTypeDefinitionOptions +{ + /// + /// Configure the driver options for all content types that share the same Stereotype. + /// In this dictionary, the 'key' denotes the Stereotype, while the 'value' corresponds to the driver options. + /// + public Dictionary Stereotypes { get; } = []; + + /// + /// Configure the driver options for each content type. + /// In this dictionary, the 'key' denotes the content type, while the 'value' corresponds to the driver options. + /// + public Dictionary ContentTypes { get; } = []; +}