From f3a7f1cfece5206f3107a1cbdde9976a9194be6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Wed, 7 Aug 2024 12:21:39 +0200 Subject: [PATCH 1/7] Post-merge fixups. --- Lombiq.TrainingDemo/Drivers/BookDisplayDriver.cs | 2 +- .../Drivers/DemoSettingsDisplayDriver.cs | 10 +++++----- .../Settings/ColorFieldSettingsDriver.cs | 7 ++++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Lombiq.TrainingDemo/Drivers/BookDisplayDriver.cs b/Lombiq.TrainingDemo/Drivers/BookDisplayDriver.cs index 71745293..1791d8c2 100644 --- a/Lombiq.TrainingDemo/Drivers/BookDisplayDriver.cs +++ b/Lombiq.TrainingDemo/Drivers/BookDisplayDriver.cs @@ -20,7 +20,7 @@ public class BookDisplayDriver : DisplayDriver "StyleCop.CSharp.ReadabilityRules", "SA1114:Parameter list should follow declaration", Justification = "Necessary for comments.")] - public override IDisplayResult Display(Book model) => + public override IDisplayResult Display(Book model, BuildDisplayContext context) => // For the sake of demonstration we use Combined() here. It makes it possible to return multiple shapes from a // driver method - won't necessarily be displayed all at once! Combine( diff --git a/Lombiq.TrainingDemo/Drivers/DemoSettingsDisplayDriver.cs b/Lombiq.TrainingDemo/Drivers/DemoSettingsDisplayDriver.cs index b9eb9c4f..d05deea1 100644 --- a/Lombiq.TrainingDemo/Drivers/DemoSettingsDisplayDriver.cs +++ b/Lombiq.TrainingDemo/Drivers/DemoSettingsDisplayDriver.cs @@ -32,10 +32,10 @@ public DemoSettingsDisplayDriver(IAuthorizationService authorizationService, IHt // Here's the EditAsync override to display editor for our site settings on the Dashboard. Note that it has a sync // version too. - public override async Task EditAsync(DemoSettings section, BuildEditorContext context) + public override async Task EditAsync(ISite model, DemoSettings section, BuildEditorContext context) { - // What you really don't want to is to let unauthorized users update site-level settings of your site so it's - // really advisable to create a separate permission for managing the settings or the feature related to this + // What you really don't want to is to let unauthorized users update site-level settings of your site. So it's + // really advisable to create a separate permission for managing the settings or the feature related to these // settings and use it here. We've created one that you can see in the Permissions/DemoSettingsPermissions.cs // file. if (!await IsAuthorizedToManageDemoSettingsAsync()) @@ -54,7 +54,7 @@ public override async Task EditAsync(DemoSettings section, Build .OnGroup(EditorGroupId); } - public override async Task UpdateAsync(DemoSettings section, UpdateEditorContext context) + public override async Task UpdateAsync(ISite model, DemoSettings section, UpdateEditorContext context) { // Since this DisplayDriver is for the ISite object this UpdateAsync will be called every time if a site // settings editor is being updated. To make sure that this is for our editor group check it here. @@ -74,7 +74,7 @@ public override async Task UpdateAsync(DemoSettings section, Upd section.Message = viewModel.Message; } - return await EditAsync(section, context); + return await EditAsync(model, section, context); } private async Task IsAuthorizedToManageDemoSettingsAsync() diff --git a/Lombiq.TrainingDemo/Settings/ColorFieldSettingsDriver.cs b/Lombiq.TrainingDemo/Settings/ColorFieldSettingsDriver.cs index 2ae42b4b..195157ad 100644 --- a/Lombiq.TrainingDemo/Settings/ColorFieldSettingsDriver.cs +++ b/Lombiq.TrainingDemo/Settings/ColorFieldSettingsDriver.cs @@ -1,18 +1,19 @@ using Lombiq.TrainingDemo.Fields; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentTypes.Editors; +using OrchardCore.DisplayManagement.Handlers; using OrchardCore.DisplayManagement.Views; using System.Text.Json.Nodes; using System.Threading.Tasks; namespace Lombiq.TrainingDemo.Settings; -// It's in the Settings folder by convention but it's the same DisplayDriver as the others; except, it also has a +// It's in the Settings folder by convention, but it's the same DisplayDriver as the others; except, it also has a // specific base class. Don't forget to register this class with the service provider (see: Startup.cs). public class ColorFieldSettingsDriver : ContentPartFieldDefinitionDisplayDriver { // This won't have a Display override since it wouldn't make too much sense, settings are just edited. - public override IDisplayResult Edit(ContentPartFieldDefinition model) => + public override IDisplayResult Edit(ContentPartFieldDefinition model, BuildEditorContext context) => // Same old Initialize shape helper. Initialize( $"{nameof(ColorFieldSettings)}_Edit", @@ -33,7 +34,7 @@ public override async Task UpdateAsync( // object. This helper will merge our settings into this JSON object so these will be stored. context.Builder.WithSettings(settings); - return Edit(model); + return await EditAsync(model, context); } } From 86baa2c2d07bc6001577fd4cb2b298a56d585def Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Wed, 7 Aug 2024 13:00:47 +0200 Subject: [PATCH 2/7] Use CreateModelAsync where applicable. --- .../Drivers/ColorFieldDisplayDriver.cs | 27 +++++++++---------- .../Drivers/DemoSettingsDisplayDriver.cs | 5 +--- .../Drivers/PersonPartDisplayDriver.cs | 11 ++++---- .../Settings/ColorFieldSettingsDriver.cs | 4 +-- 4 files changed, 20 insertions(+), 27 deletions(-) diff --git a/Lombiq.TrainingDemo/Drivers/ColorFieldDisplayDriver.cs b/Lombiq.TrainingDemo/Drivers/ColorFieldDisplayDriver.cs index 7906ef7d..d3443e2b 100644 --- a/Lombiq.TrainingDemo/Drivers/ColorFieldDisplayDriver.cs +++ b/Lombiq.TrainingDemo/Drivers/ColorFieldDisplayDriver.cs @@ -63,24 +63,23 @@ public override async Task UpdateAsync(ColorField field, IUpdate // Using this overload of the model updater you can specifically say what properties need to be updated. This // way you make sure no other properties will be bound to the view model. Instead of this you could put // [BindNever] attributes on the properties to make the model binder to skip those, it's up to you. - if (await updater.TryUpdateModelAsync(viewModel, Prefix, f => f.Value, f => f.ColorName)) + await updater.TryUpdateModelAsync(viewModel, Prefix, viewModel => viewModel.Value, viewModel => viewModel.ColorName); + + // Get the ColorFieldSettings to use it when validating the view model. + var settings = context.PartFieldDefinition.GetSettings(); + if (settings.Required && string.IsNullOrWhiteSpace(viewModel.Value)) { - // Get the ColorFieldSettings to use it when validating the view model. - var settings = context.PartFieldDefinition.GetSettings(); - if (settings.Required && string.IsNullOrWhiteSpace(viewModel.Value)) - { - updater.ModelState.AddModelError(Prefix, T["A value is required for {0}.", context.PartFieldDefinition.DisplayName()]); - } + updater.ModelState.AddModelError(Prefix, T["A value is required for {0}.", context.PartFieldDefinition.DisplayName()]); + } - // Also some custom validation for our ColorField hex value. - var isInvalidHexColor = !string.IsNullOrWhiteSpace(viewModel.Value) && - !RegexExpression().IsMatch(viewModel.Value); + // Also some custom validation for our ColorField hex value. + var isInvalidHexColor = !string.IsNullOrWhiteSpace(viewModel.Value) && + !RegexExpression().IsMatch(viewModel.Value); - if (isInvalidHexColor) updater.ModelState.AddModelError(Prefix, T["The given color is invalid."]); + if (isInvalidHexColor) updater.ModelState.AddModelError(Prefix, T["The given color is invalid."]); - field.ColorName = viewModel.ColorName; - field.Value = viewModel.Value; - } + field.ColorName = viewModel.ColorName; + field.Value = viewModel.Value; return await EditAsync(field, context); } diff --git a/Lombiq.TrainingDemo/Drivers/DemoSettingsDisplayDriver.cs b/Lombiq.TrainingDemo/Drivers/DemoSettingsDisplayDriver.cs index d05deea1..4ade34d9 100644 --- a/Lombiq.TrainingDemo/Drivers/DemoSettingsDisplayDriver.cs +++ b/Lombiq.TrainingDemo/Drivers/DemoSettingsDisplayDriver.cs @@ -67,10 +67,7 @@ public override async Task UpdateAsync(ISite model, DemoSettings } // Update the view model and the settings model as usual. - var viewModel = new DemoSettingsViewModel(); - - await context.Updater.TryUpdateModelAsync(viewModel, Prefix); - + var viewModel = await context.CreateModelAsync(Prefix); section.Message = viewModel.Message; } diff --git a/Lombiq.TrainingDemo/Drivers/PersonPartDisplayDriver.cs b/Lombiq.TrainingDemo/Drivers/PersonPartDisplayDriver.cs index e41aa70b..2d2d9c82 100644 --- a/Lombiq.TrainingDemo/Drivers/PersonPartDisplayDriver.cs +++ b/Lombiq.TrainingDemo/Drivers/PersonPartDisplayDriver.cs @@ -2,6 +2,7 @@ using Lombiq.TrainingDemo.ViewModels; using OrchardCore.ContentManagement.Display.ContentDisplay; using OrchardCore.ContentManagement.Display.Models; +using OrchardCore.DisplayManagement.Handlers; using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; using System.Threading.Tasks; @@ -27,7 +28,7 @@ public class PersonPartDisplayDriver : ContentPartDisplayDriver public override IDisplayResult Display(PersonPart part, BuildPartDisplayContext context) => // Here you have a shape helper with a shape name possibly and a factory. The Initialize method will instantiate // a view model from a type given as a generic parameter. It's recommended to use view models for the views like - // we're doing it here (sometimes you'd want a separate view model for the Display() and Edit(). There are + // we're doing it here (sometimes you'd want a separate view model for the Display() and Edit()). There are // helper methods to generate the shape type. GetDisplayShapeType() in this case will generate "PersonPart" by // default but this can be overridden form the part's settings under the content type's settings on the admin. // In the factory we map the content part properties to the view model; if there is any heavy lifting needed to @@ -75,14 +76,12 @@ public override IDisplayResult Edit(PersonPart part, BuildPartEditorContext cont // part-specific model binding and validation. public override async Task UpdateAsync(PersonPart part, IUpdateModel updater, UpdatePartEditorContext context) { - var viewModel = new PersonPartViewModel(); - // Via the IUpdateModel you will be able to use the current controller's model binding helpers here in the // driver. The prefix property will be used to distinguish between similarly named input fields when building // the editor form (so e.g. two content parts composing a content item can have an input field called "Name"). - // By default Orchard Core will use the content part name but if you have multiple drivers with editors for a + // By default, Orchard Core will use the content part name but if you have multiple drivers with editors for a // content part you need to override it in the driver. - await updater.TryUpdateModelAsync(viewModel, Prefix); + var viewModel = await context.CreateModelAsync(Prefix); // Now you can do some validation if needed. One way to do it you can simply write your own validation here or // you can do it in the view model class. @@ -90,7 +89,7 @@ public override async Task UpdateAsync(PersonPart part, IUpdateM // Go and check the ViewModels/PersonPartViewModel to see how to do it and then come back here. // Finally map the view model to the content part. By default, these changes won't be persisted if there was a - // validation error. Otherwise these will be automatically stored in the database. + // validation error. Otherwise, these will be automatically stored in the database. part.BirthDateUtc = viewModel.BirthDateUtc; part.Name = viewModel.Name; part.Handedness = viewModel.Handedness; diff --git a/Lombiq.TrainingDemo/Settings/ColorFieldSettingsDriver.cs b/Lombiq.TrainingDemo/Settings/ColorFieldSettingsDriver.cs index 195157ad..bc554096 100644 --- a/Lombiq.TrainingDemo/Settings/ColorFieldSettingsDriver.cs +++ b/Lombiq.TrainingDemo/Settings/ColorFieldSettingsDriver.cs @@ -26,9 +26,7 @@ public override async Task UpdateAsync( ContentPartFieldDefinition model, UpdatePartFieldEditorContext context) { - var settings = new ColorFieldSettings(); - - await context.Updater.TryUpdateModelAsync(settings, Prefix); + var settings = await context.CreateModelAsync(Prefix); // A content field or a content part can have multiple settings. These settings are stored in a single JSON // object. This helper will merge our settings into this JSON object so these will be stored. From 78e3783b19e0076a8859ab59cd48a22acb9dfea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Wed, 7 Aug 2024 13:53:57 +0200 Subject: [PATCH 3/7] Update HL alpha version. --- Lombiq.TrainingDemo/Lombiq.TrainingDemo.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lombiq.TrainingDemo/Lombiq.TrainingDemo.csproj b/Lombiq.TrainingDemo/Lombiq.TrainingDemo.csproj index ade1d604..c13231b6 100644 --- a/Lombiq.TrainingDemo/Lombiq.TrainingDemo.csproj +++ b/Lombiq.TrainingDemo/Lombiq.TrainingDemo.csproj @@ -51,7 +51,7 @@ - + From 877991a8685ab63be52ec3cc814b2269093346b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1ra=20El-Saig?= Date: Wed, 7 Aug 2024 17:38:12 +0200 Subject: [PATCH 4/7] Update OC preview version. --- .../Lombiq.TrainingDemo.Web.csproj | 6 ++-- .../Lombiq.TrainingDemo.csproj | 28 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Lombiq.TrainingDemo.Web/Lombiq.TrainingDemo.Web.csproj b/Lombiq.TrainingDemo.Web/Lombiq.TrainingDemo.Web.csproj index 226153af..aee7086a 100644 --- a/Lombiq.TrainingDemo.Web/Lombiq.TrainingDemo.Web.csproj +++ b/Lombiq.TrainingDemo.Web/Lombiq.TrainingDemo.Web.csproj @@ -18,11 +18,11 @@ - - + + - + diff --git a/Lombiq.TrainingDemo/Lombiq.TrainingDemo.csproj b/Lombiq.TrainingDemo/Lombiq.TrainingDemo.csproj index c13231b6..6c6b56e5 100644 --- a/Lombiq.TrainingDemo/Lombiq.TrainingDemo.csproj +++ b/Lombiq.TrainingDemo/Lombiq.TrainingDemo.csproj @@ -22,24 +22,24 @@ - - - - - - - - - - - - + + + + + + + + + + + + - - + + - + diff --git a/Lombiq.TrainingDemo/Lombiq.TrainingDemo.csproj b/Lombiq.TrainingDemo/Lombiq.TrainingDemo.csproj index 6c6b56e5..1e043ca8 100644 --- a/Lombiq.TrainingDemo/Lombiq.TrainingDemo.csproj +++ b/Lombiq.TrainingDemo/Lombiq.TrainingDemo.csproj @@ -22,24 +22,24 @@ - - - - - - - - - - - - + + + + + + + + + + + + - - + +