Extend the Admin Interface in NopCommerce 4.2
What if you wanted to create a plugin that extends, for example, the product entity? This tutorial shows an alternative way to the classical approach of adding a configuration site.
Basically, you could create a basic configuration page that offers standard CRUD operations, as described in the nopCommerce docs. This approach might be adequate for a plugin that adds new functionality to the system, but I find it cumbersome in the case of an extension. Instead, I prefer to extend the existing editing page of an entity. For this example, I am going to add a tab to add or edit related blog posts - similar to the concept of related products. I am going to skip the data layer part to keep this post as short as possible (see https://docs.nopcommerce.com/developer/plugins/plugin-with-data-access.html for information on how to extend the data layer).
I wrote this tutorial for NopCommerce 4.2, but its concepts also apply for older as well as new versions. The most noticeable difference between the current and older versions is the approach on how to extend an existing admin page. While older versions required implementation of an event consumer and adding the HTML within that code, the most recent release of nopCommerce offers a much more beautiful way by using a widget zone.
Create a new plugin that implements IWidgetPlugin and configure the widget zone to use (How to create a new plugin in NopCommerce: https://docs.nopcommerce.com/developer/plugins/index.html).
NopCommerce requires you to create a bunch of models for this to work. The first three models back the newly added section on the editing page and its contained list of existing related blogs. To keep things tidy, I decided to pack those models into one file:
The class RelatedBlogPostModel defines the list data, the system uses RelatedBlogPostSearchModel to load the list data, and RelatedBlogPostListModel holds the list data.
The three following models do the same as the latter but for the popup to add a new entry. They look pretty similar except for the search model since we want to have a search interface in the popup.
Lastly, we extend the product model with an instance of RelatedBlogPostSearchModel (I don't extend the product model in a programmatic sense as it would add overhead).
In the next step, we implement the necessary views. The first one is the components default view (we define the component later), so we call it Default.cshtml. It contains quite a bit of code but basically what it does is it defines the data grid and fills it with data fetched from the controller via RelatedBlogPostList (We implement this method in the next step). The rest should be self-explanatory.