Adding functionality to Nopcommerce's admin screens without copying and pasting existing views


Introduction

Nopcommerce's plugin engine is fairly powerful, providing extension points to expand core functionality. A sizable ecosystem has been built aroudn these extension points. When it works, it adds a lot whole lot of value. However, oftentimes required extension points do not exist, and extending the platform becomes much trickier.

In the past I have made modifications directly to the Admin site, but this leads to maintenance pain and I much prefer a plugin approach. In this post, I'll outline how I developed a trivial plugin, adding a button to the Order List screen, without duplicating any code.

Background

For a long time administrators on my site have been able to print delivery labels from the Order List and Order Details screens. This requires adding a button to these screens, adding some Javascript to these screens and also adding some controller code. The result looks something like this:

As of right now, Nopcommerce does not have much support for admin page modifications. There are a limited number of widget zones (allowing custom widgets to be placed on screen) and otherwise very limited UI customizability.

Standard Suggestion

The most common advice you see in these situations is to create a plugin, create a new view engine and point it to customized versions of the existing cshtml view files. So, in my case, I'd take a copy of Orders\Edit.cshtml and Orders\List.cshtml, modify them with my desired behavior and point my viewengine at the modified files. In theory this is fine, and it works well for small partial views. However, for the two files in question we're looking at a totalk of 700+ lines of code being duplicated.

My Solution

The solution in my case is similar to the above, but without the redundancy implied by duplicate code.

Step 1: Create as Misc plugin

I'll asume the reader is experienced enough with Nopcommerce to complete this step without help

Step 2: Create Your View Engine

All we're doing here is telling the plugin where to find our views.

undefined

Step 3: Create Your Routeprovider

This step is pretty straightforward. The goal is to overwrite the routes that the admin page currently uses when listing/editing orders.


Step 4: Create your Controller

It doesn't get much more simple than this

Step 5: Create Your Views

So here's where the magic happens. Rather than duplicating and modifying the original view, we render it as an action in our new view, adding our button(s) and events via jQuery. Below is an example of my List.cshtml view. Orders.cshtml works the same way.

Assuming future changes by the Nopcommerce team are not too impactful, this plugin should continue to work without requiring any re-coding.

Potential Drawbacks

This is far from a perfect solution.

1. It potentially has a performance impact as view processing will take a little longer due to the nested nature of our action rendering. To me, this is insignifcant. I'm not sure if the difference is noticable and, even if it is, I am more concerned about consumer-facing and search-engine-facing performance than performance that my administrators see.

2. You can only do this once per screen. By that I mean, you can't have multiple plugins ammending the same screen. Remember, we are overriding our route list, replacing the default with our own routes. If we do this more than once, the last in wins...whichever routes are loaded last will determine what is seen by the user.

In Closing

Look, this is a hack. Undoubtedly so. At some point in the near future the Nopcomerce team will expand upon the available widget zones in the admin area and/or add further extension points to the admin panel, making all of this unnecessary. When they do, I will most certainly update my code. But, in the short term, this allows additional value to be addded to administrative screens without having to copy and paste a bunch of code.

Popular posts from this blog

Excel - Adding an existing Pivot table to the data model

Mirth

Getting Started with Mirth (Part 1)