Content Part Display Driver
In Orchard Core, the ContentPartDisplayDriver is a powerful mechanism to control the rendering and editing of content parts. A driver offers advanced functionality such as dynamic behaviours, reusability, and backend-driven customisations.
Setup View Model
We need to have a view model setup to isolate the data preparation logic from the ContentPart and display driver. The view only interacts with the view model making it easier to handle complex data structures. A view model is an excellent way to handle validation in Orchard Core. By applying data annotations (such as [Required], [StringLength], [Range], etc.) to the properties of your ViewModel, you can validate user input in a clean and structured way.
For example, we can have the view model for our Product Information as follows under /ViewModels/ in the module folder.
using System.ComponentModel.DataAnnotations;
using OrchardCore.Media.Fields;
namespace OCBC.ProductModule.ViewModels;
public class ProductInformationPartViewModel
{
[Required]
public string ProductName { get; set; }
[Required]
public string ChineseProductName { get; set; }
[Required]
public string Model { get; set; }
public string Description { get; set; }
public MediaField[] ProductImages { get; set; }
}In the code above, we are using MediaField, which is. Hence we will need to add the following NuGet package.
Setup Display Driver
The ContentPartDisplayDriver in Orchard Core primarily focuses on handling the display, edit, and update workflows for a content part.
Display handles the rendering of the part when the content item is viewed;
Edit handles the rendering of the part when the content item is being edited;
UpdateAsync handles the processing and updating of the part when the form is submitted.
To enable our Content Part using the display driver, we need to tell it which display driver to use in the configuration of the module with UseDisplayDriver.
After that, we can proceed to create a new display driver class for our Product Information Part called ProductInformationPartDisplayDriver. It can be placed in the Drivers folder in the module.
Edit View
For the display driver, we will setup the Edit part as follow.
This method defines how the Edit interface for a ContentPart (in this case, ProductInformationPart) is rendered in the Administration UI. It is triggered when the system needs to build the editing interface for the ProductInformationPart. Here, the view model ProductInformationPartViewModel bridges the content type ProductInformationPart and the Razor view.
The method GetEditorShapeType(context) dynamically determines the name of the shape to use for rendering. Typically it resolves to <PartName>.Edit.cshtml under /Views/ in the module folder.
In Orchard Core, a "shape" is a key concept in the display management system. It represents a flexible and dynamic UI component that can be rendered as part of our content.
Finally, the Location("Content:5") is to specify where the shape should be rendered in the UI. In this case, we use Content, which indicates the zone in which the shape will be rendered while the 5 after it specifies the priority or order in which the shape appears relative to other shapes in the same zone. Lower numbers render first.
With this setup, we can setup the Razor view for the Edit view. What we need to do is create a ProductInformationPart.Edit.cshtml file under Views folder with the following code.
The code above should render the following UI.

As shown in the screenshot above, the Product Images field is not in our ProductInformationPart.Edit.cshtml but how come the image field is still rendered? In Orchard Core, even if we do not explicitly add HTML for a field in our Edit.cshtml, the field can still render automatically if it is registered via the WithField method in the DisplayDriver. This behaviour occurs because Orchard Core uses the Shape system to render fields.
When we submit a form with data, the submitted values are sent to the server as part of the HTTP POST request. However, this raw data will not automatically populate our server-side ViewModel. Hence, we need to extract the values from the request and map them to the correct model properties. This is where context.Updater.TryUpdateModelAsync comes into play in the display driver.
The concept of "binding using the correct prefix" comes into play here where we have multiple models or parts on a page, and we want to ensure that form values are bound correctly to the right model properties.
Before leaving the method, we also update the DisplayText so that the listing of Content Items on Administration UI will give us useful names instead of the default "Product Information", which is the Content Type name.

Finally, we must save the changes to the database asynchronously, which is done with the EditAsync.
Edit View - More MediaFields
It is not fun with just one product image. Let's allow users to upload three images for each of the product.
Firstly, we update the migration as follows (Your migration number may be different).
Secondly, we will update our display driver as follows.
Thirdly, before we proceed to update the Edit view, we will find out that the three MediaFields have already been displayed.

We can customise them with CSS in the cshtml file so that the three MediaFields appear side by side.
We will then get the following UI for the Edit.

Display View
We can continue to setup our display driver for the Display view, as shown below.
The Display method creates the display logic for rendering our ProductInformationPart in the Details context.
We thus need to create a ProductInformationPart.Detail.cshtml file under Views folder with the following code.
The code above will render the following web page when we are visiting one of the products.

Last updated