Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NopCommerce customization

I am starting an eCommerce website and decided to start with NopCommerce V4.00. I have developed other websites using WordPress and other CMS systems along with C#, .NET, MVC etc. but I am not familiar with NopCommerce and I am looking for some suggestions on what the best way of tackling the customization is.

This site is going to require some extensive customization and one of the concerns that I have is in regards to maintainability and updates. I need to make sure that I am not shooting myself in the foot and really making things difficult when the time comes to upgrade to a new version of NopCommernce. I learned long ago to always try and add on top of these systems and leave the system code alone whenever possible.

I found this question in regards to overriding the views and if I am assuming correctly if the view is present under the theme (following the same structure) then that view will be used otherwise the default view is used from the root 'Views' Folder?

I can't seem to find much about customizing the Admin side of the site and not sure how to customize it without touching the source. Basically what I need to accomplish is provide a trimmed down version of the Admin area, a "Dummy Proof" version if you will. Would it be wiser to use the Access Control and possibly custom Customer Roles to hide any areas that I need to provide a custom interface for, such as entering new Products or Attributes and provide a Plugin instead and add that to the Admin Menu? Or would it be better to do this whole thing as a totally separate Plugin on the Public side and leave the admin side totally out of it? I have not had enough experience with this system yet and I want to avoid any permission problems and/or opening up any holes in the security since it is in a separate Area.

I would also appreciate any tips or gotcha's that I should be aware of with NopCommerce in general. I have found quite a few sites but these all seem to reference V2 or V3 and I am not sure if there have been any major changes since then.

Thanks!


Update

In case there are others that are looking for this same information, in addition to the answer I was able to find a couple of links that others might find useful that address this.

  • NopCommernce Forum - Override Admin Views and Admin Controllers

  • Overriding NopCommerce Admin Views and Partial Views

  • Overriding and Adding Views With a NopCommerce Plugin

  • 3 Ways to Display Views in Your nopCommerce Plugins (Embedded Resource, Theme Override and Custom View Engine)

  • Override Existing Controller & Action in Nop Version 4.0

  • Where to register custom view engine in Nop 4.0

like image 368
Andy Braham Avatar asked May 25 '18 09:05

Andy Braham


Video Answer


2 Answers

First, you should not add more than one question at a time, you can ask as many as question you want but separately !

Maintainability and updates.

As per as I worked with nopCommerce, it's easy to maintain and upgrade the project. However, it depends on what practices you will be following. There are several common ways to make custom code over default code. The best way is to develop a plugin for your requirement(s), which will make upgradation process seamless.

But, when nopCommerce move to the newer technology, it will a hassles to update your existing site, that what happened on upgradation of nopCommerce 3.90 to 4.0, It was drastic change to move to the ASP.NET Core. But with appropriate knowledge of technology you can do it easily.

I learned long ago to always try and add on top of these systems and leave the system code alone whenever possible

Yes, that is the most preferable by developers, do not touch the default code and run your code on top of system, and that's what plugable architecture is use for.

if the view is present under the theme (following the same structure) then that view will be used otherwise the default view is used from the root 'Views' Folder?

Yes, first it render view pages under theme folder, then following by root view pages. Both can override from plugin.

how to customize it without touching the source

Create your plugin with functionality you want and inject it to system code.

Would it be wiser to use the Access Control and possibly custom Customer Roles to hide any areas that I need to provide a custom interface for, such as entering new Products or Attributes and provide a Plugin instead and add that to the Admin Menu.

You can create new roles and handle ACL(Access Control List)

Or would it be better to do this whole thing as a totally separate Plugin on the Public side and leave the admin side totally out of it?

It depends on your requirement, if you would like to make changes at admin side or front side, both things can manage from the plugin.

Hope this helps!

like image 180
Divyang Desai Avatar answered Oct 10 '22 03:10

Divyang Desai


I found a couple of things that are worth mentioning. Like the accepted answer pointed out NopCommernce went some major changes in V4.0 most notably going to .Net Core, this changes quite a few things especially in regards to CustomViewEngines which was the prefered method for overriding views.

Now that things are running on .Net Core there is another method, IViewLocationExpander.

For example to overwrite the _AdminLayout.cshtml that is rendered first a ViewLocationExpander class is required:

ViewLocationExpander

public class ViewLocationExpander : IViewLocationExpander
{
    public void PopulateValues(ViewLocationExpanderContext context)
    {
    }

    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
    {
        // Since we are wanting to override the Admin template just look for Admin in the Context, you can also get the controller and view names here.
        if (context.AreaName == AreaNames.Admin)
        {
            //Add the location we want to use instead
            viewLocations = new string[] { $"/Plugins/YourPlugin/Views/Admin/{{1}}/{{0}}.cshtml",
                                          $"/Plugins/YourPlugin/Views/Admin/Shared/{{0}}.cshtml"}.Concat(viewLocations);
        }

        return viewLocations;
    }
}

Then a Startup file is needed to tell NopCommerence to use this new ViewLocationExpander. The NopCommerence Engine finds all classes implementing INopStartup and executes them on startup.

YourPluginStartup.cs

public class StoreManagerStartup : INopStartup
{
    public void ConfigureServices(IServiceCollection services, IConfigurationRoot configuration)
    {
        services.Configure<RazorViewEngineOptions>(options =>
        {
            options.ViewLocationExpanders.Add(new ViewLocationExpander());
        });
    }

    public void Configure(IApplicationBuilder application)
    {
    }

    public int Order {
        get { return 0; } //Return 0 to force this to execute first, otherwise set higher i.e. 1001 
    }

}

One thing I found when doing this as a Plugin was I had to add some references to the _AdminLayout.cshtml template along with the appropriate Projects.

_AdminLayout.cshtml (header only, code ommited)

@inject IWebHelper webHelper
@inject IWorkContext workContext
@inject IDateTimeHelper dateTimeHelper
@inject IPermissionService permissionService
@inject IEventPublisher eventPublisher
@inject IHttpContextAccessor httpContextAccessor
@inject CommonSettings commonSettings
@inject LocalizationSettings localizationSettings
@inject StoreInformationSettings storeInformationSettings
@using System.Globalization;
@using System.Text.Encodings.Web;
@using Microsoft.AspNetCore.Http;
@using Nop.Core.Domain.Customers;
@using Nop.Web.Framework;
@using Nop.Web.Framework.Events;
@using Nop.Web.Framework.UI;
@using Nop.Core;
@using Nop.Core.Domain;
@using Nop.Core.Domain.Common;
@using Nop.Core.Domain.Localization;
@using Nop.Services.Common;
@using Nop.Services.Customers;
@using Nop.Services.Events;
@using Nop.Services.Helpers;
@using Nop.Services.Security;

If you are only wanting to add to the Admin Menu simply inherit from the IAdminMenuPlugin interface like so:

public class YourPlugin : BasePlugin, IAdminMenuPlugin
{
    private readonly ISettingService _settingService;
    private readonly IWebHelper _webHelper;

    /**
     * Constructor
     **/
    public YourPlugin(ISettingService settingService, IWebHelper webHelper)
    {
        this._settingService = settingService;
        this._webHelper = webHelper;
    }

    /**
     * Adds the Admin Menu Item
     **/
    public void ManageSiteMap(SiteMapNode rootNode)
    {
        var menuItem = new SiteMapNode()
        {
            SystemName = "Plugins.YourPlugin",
            Title = "Your Plugin Title",
            ControllerName = "YourPlugin",
            ActionName = "Configure",
            Visible = true,
            RouteValues = new RouteValueDictionary() { { "area", null } },
        };

        // To add to the root Admin menu use
        rootNode.ChildNodes.Insert(1, menuItem); // or rootNode.ChildNodes.Add(menuItem);

        /* uncomment to add to the "Plugins" Menu Item
        var pluginNode = rootNode.ChildNodes.FirstOrDefault(x => x.SystemName == "Third party plugins");

        if (pluginNode != null)
            pluginNode.ChildNodes.Add(menuItem);
        else
            rootNode.ChildNodes.Add(menuItem);
        */
    }
}

Dont forget to add any _ViewStart.cshtml files if you are overriding the index pages otherwise the Templates will not be loaded.

like image 26
Andy Braham Avatar answered Oct 10 '22 03:10

Andy Braham