代码之家  ›  专栏  ›  技术社区  ›  Andy Braham

非商业定制

  •  6
  • Andy Braham  · 技术社区  · 6 年前

    我正在创建一个电子商务网站,并决定从nopcommerce v4.00开始。我使用WordPress和其他CMS系统以及C、.net、MVC等开发了其他网站,但我不熟悉NoCommerce,我正在寻找解决定制问题的最佳方法的建议。

    这个站点将需要一些广泛的定制,我关心的一个问题是可维护性和更新。我需要确保在升级到新版本的nocommence时,我不会把自己的脚射伤,也不会让事情变得困难。我很久以前就学会了总是尝试在这些系统的基础上添加代码,并且尽可能地让系统代码单独存在。

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

    我似乎找不到太多关于定制网站的管理方面的内容,也不知道如何在不触及源代码的情况下定制它。基本上,我需要完成的是提供一个管理区域的精简版本,如果愿意的话,提供一个“虚拟证明”版本。使用访问控制和可能的自定义客户角色来隐藏我需要为其提供自定义界面的任何区域是否更明智,例如输入新产品或属性并提供插件,然后将其添加到管理菜单?或者,将整个事情作为一个完全独立的插件在公共端完成,让管理端完全脱离它会更好吗?我对这个系统还没有足够的经验,我想避免任何许可问题和/或打开任何安全漏洞,因为它在一个单独的区域。

    我也会感谢任何我应该知道的关于nopcommerce的小贴士。我已经找到了相当多的站点,但这些站点似乎都引用了v2或v3,我不确定从那时起是否有任何重大变化。

    谢谢!


    更新

    如果有其他人在寻找同样的信息,除了答案之外,我还可以找到一些其他人可能会发现有用的链接来解决这个问题。

    2 回复  |  直到 6 年前
        1
  •  7
  •   Divyang Desai Jonny B'Good    6 年前

    首先,一次不应添加多个问题,您可以提出任意多个问题,但 分开!

    可维护性和更新。

    根据我在nopcommerce的工作,很容易维护和升级项目。但是,这取决于您将遵循什么实践。有几个 常见的 使自定义代码优于默认代码的方法。最好的方法是为您的需求开发一个插件,这将使升级过程无缝。

    但是,当nopcommerce迁移到新技术时,更新现有站点会很麻烦,在nopcommerce 3.90升级到4.0时发生了什么,迁移到ASP.NET核心是一个巨大的变化。但是有了适当的技术知识,你就可以很容易地做到。

    我很久以前就学会了总是在这些系统的基础上尝试和添加,并且尽可能地让系统代码单独存在。

    是的,这是开发人员最可取的方法,不要触摸默认代码并在系统顶部运行代码,这就是可插入体系结构的用途。

    如果视图出现在主题下(遵循相同的结构) 然后将使用该视图,否则将使用默认视图 根“视图”文件夹?

    是的,首先在主题文件夹下呈现视图页,然后按根视图页。两者都可以从插件重写。

    如何在不接触源的情况下自定义它

    使用所需的功能创建插件,并将其注入系统代码。

    使用访问控制和可能的自定义是否更明智? 客户角色隐藏我需要提供自定义 接口,例如输入新产品或属性并提供 而是一个插件,并将其添加到管理菜单中。

    您可以创建新角色并处理ACL( Access Control List )

    或者,将整个事情作为一个完全独立的插件在公共端完成,让管理端完全脱离它会更好吗?

    这取决于您的需求,如果您想在管理端或前端进行更改,这两个方面都可以从插件进行管理。

    希望这有帮助!

        2
  •  3
  •   Andy Braham    6 年前

    我发现了一些值得一提的事情。正如公认的答案所指出的那样,v4.0中没有通信发生了一些重大的变化,尤其是对.NET核心的变化,这改变了很多事情,特别是对于CustomViewEngines,它是首选的覆盖视图的方法。

    现在.NET核心上运行的是另一种方法, IViewLocationExpander(位置扩展程序) .

    例如,要覆盖首先呈现的_adminlayout.cshtml,需要一个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;
        }
    }
    

    然后需要一个启动文件来告诉nocommerence使用这个新的viewlocationexpander。nocommerence引擎查找所有实现inopstartup的类,并在启动时执行它们。

    您的plugintartup.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(仅限标题,代码已修改)

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

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