NopCommerce定制

NopCommerce customization

我正在创建一个电子商务网站,并决定从 NopCommerce V4.00 开始。我已经使用 WordPress 和其他 CMS 系统以及 C#、.NET、MVC 等开发了其他网站,但我不熟悉 NopCommerce,我正在寻找一些关于处理自定义的最佳方法的建议。

该站点将需要进行一些广泛的定制,而我所关心的问题之一是可维护性和更新。我需要确保在升级到 NopCommernce 的新版本时,我不会搬起石头砸自己的脚,真的让事情变得困难。我很久以前就学会了总是尝试在这些系统之上添加并尽可能地保留系统代码。

我发现 this question 关于覆盖视图,如果我假设正确,如果视图存在于主题下(遵循相同的结构),那么将使用该视图,否则将使用默认视图从根 'Views' 文件夹?

我似乎找不到太多关于自定义网站管理端的信息,也不确定如何在不接触源代码的情况下对其进行自定义。基本上我需要完成的是提供管理区域的精简版本,如果您愿意,可以提供 "Dummy Proof" 版本。使用访问控制和可能的自定义客户角色来隐藏我需要为其提供自定义界面的任何区域是否更明智,例如输入新产品或属性并提供插件并将其添加到管理菜单?或者将整个事情作为 Public 端的一个完全独立的插件来完成,而让管理端完全脱离它会更好吗?我对这个系统还没有足够的经验,我想避免任何权限问题 and/or 因为它在一个单独的区域中,所以会打开任何安全漏洞。

我也很感激任何我应该知道的关于 NopCommerce 的提示或问题。我找到了很多网站,但这些网站似乎都引用了 V2 或 V3,我不确定此后是否有任何重大变化。

谢谢!


更新

如果有其他人正在寻找相同的信息,除了答案之外,我还找到了几个其他人可能会觉得有用的链接来解决这个问题。

首先,您一次添加的问题不应超过一个,您可以想问多少就问多少,但是分开!

Maintainability and updates.

根据我在 nopCommerce 的工作,维护和升级项目很容易。但是,这取决于您将遵循的做法。有几种常见 方法可以在默认代码上创建自定义代码。最好的方法是根据您的要求开发一个插件,这将使升级过程无缝进行。

但是,当 nopCommerce 转向更新的技术时,更新您现有的网站会很麻烦,将 nopCommerce 3.90 升级到 4.0 时发生的事情,转向 ASP.NET 核心是巨大的变化.但是只要具备适当的技术知识,您就可以轻松做到。

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

是的,这是开发人员最喜欢的,不要触及默认代码,运行您的代码在系统之上,这就是可插拔架构的用途。

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?

是的,它首先呈现主题文件夹下的视图页面,然后是根视图页面。两者都可以从插件覆盖。

how to customize it without touching the source

创建具有所需功能的插件并将其注入系统代码。

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.

您可以创建新角色并处理 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?

这取决于您的要求,如果您想在管理端或前端进行更改,两者都可以通过插件进行管理。

希望对您有所帮助!

我发现了一些值得一提的事情。正如公认的答案所指出的那样,NopCommernce 在 V4.0 中进行了一些重大更改,最显着的是转向了 .Net Core,这改变了很多事情,尤其是在 CustomViewEngines 方面,这是覆盖视图的首选方法。

现在 .Net Core 上的东西是 运行 还有另一种方法,IViewLocationExpander

例如,要覆盖首先呈现的 _AdminLayout.cshtml,需要 ViewLocationExpander class:

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;
    }
}

然后需要一个启动文件来告诉NopCommerence 使用这个新的ViewLocationExpander。 NopCommerence 引擎找到所有实施 INopStartup 的 classes 并在启动时执行它们。

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 
    }

}

作为插件执行此操作时我发现的一件事是我必须添加一些对 _AdminLayout.cshtml 模板的引用以及适当的项目。

_AdminLayout.cshtml(仅限 header,省略代码)

@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;

如果您只想添加到管理菜单,只需继承 IAdminMenuPlugin 接口,如下所示:

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);
        */
    }
}

如果要覆盖索引页,请不要忘记添加任何 _ViewStart.cshtml 文件,否则将不会加载模板。