nop支持多店,結合NivoSlider插件介紹下如何開發支持多商城的小部件 ...
一.基礎介紹
nop支持多店及多語言,本篇結合NivoSlider插件介紹下如何開發支持多商城的小部件。
主要介面如下:
ISettingService 介面:設置介面,可實現多店配置。
ILocalizationService 介面:本地化資源介面,配合語言,實現多語言的顯示。
二.插件安裝、卸載
我們在上一篇介紹了小部件如何使用(點擊這裡),這裡介紹下如何安裝、卸載插件。
【後臺管理】【插件管理】【本地插件】可以對插件進行安裝、卸載
Nop.Admin.Controllers.PluginController控制器用於插件的管理。Install負責安裝插件、Uninstall負責卸載插件。
所有插件都繼承IPlugin介面,Install(),Uninstall()分別用於安裝及卸載。
1 namespace Nop.Core.Plugins 2 { 3 /// <summary> 4 /// Interface denoting plug-in attributes that are displayed throughout 5 /// the editing interface. 6 /// </summary> 7 public interface IPlugin 8 { 9 /// <summary> 10 /// Gets or sets the plugin descriptor 11 /// </summary> 12 PluginDescriptor PluginDescriptor { get; set; } 13 14 /// <summary> 15 /// Install plugin 16 /// </summary> 17 void Install(); 18 19 /// <summary> 20 /// Uninstall plugin 21 /// </summary> 22 void Uninstall(); 23 } 24 } 25
BasePlugin抽象類繼承了IPlugin介面,並實現了 Install(),Uninstall()方法,當安裝時在"~/App_Data/InstalledPlugins.txt"文件中寫入插件的SystemName,卸載時則在文件中刪除。
1 namespace Nop.Core.Plugins 2 { 3 /// <summary> 4 /// Base plugin 5 /// </summary> 6 public abstract class BasePlugin : IPlugin 7 { 8 /// <summary> 9 /// Gets or sets the plugin descriptor 10 /// </summary> 11 public virtual PluginDescriptor PluginDescriptor { get; set; } 12 13 /// <summary> 14 /// Install plugin 15 /// </summary> 16 public virtual void Install() 17 { 18 PluginManager.MarkPluginAsInstalled(this.PluginDescriptor.SystemName); 19 } 20 21 /// <summary> 22 /// Uninstall plugin 23 /// </summary> 24 public virtual void Uninstall() 25 { 26 PluginManager.MarkPluginAsUninstalled(this.PluginDescriptor.SystemName); 27 } 28 29 } 30 } 31
我們看下NivoSlider插件在安裝時都做了哪些操作。
1 using System.Collections.Generic; 2 using System.IO; 3 using System.Web.Routing; 4 using Nop.Core; 5 using Nop.Core.Plugins; 6 using Nop.Services.Cms; 7 using Nop.Services.Configuration; 8 using Nop.Services.Localization; 9 using Nop.Services.Media; 10 11 namespace Nop.Plugin.Widgets.NivoSlider 12 { 13 /// <summary> 14 /// PLugin 15 /// </summary> 16 public class NivoSliderPlugin : BasePlugin, IWidgetPlugin 17 { 18 private readonly IPictureService _pictureService; 19 private readonly ISettingService _settingService; 20 private readonly IWebHelper _webHelper; 21 22 public NivoSliderPlugin(IPictureService pictureService, 23 ISettingService settingService, IWebHelper webHelper) 24 { 25 this._pictureService = pictureService; 26 this._settingService = settingService; 27 this._webHelper = webHelper; 28 } 29 30 /// <summary> 31 /// Gets widget zones where this widget should be rendered 32 /// </summary> 33 /// <returns>Widget zones</returns> 34 public IList<string> GetWidgetZones() 35 { 36 return new List<string> { "home_page_top" }; 37 } 38 39 /// <summary> 40 /// Gets a route for provider configuration 41 /// </summary> 42 /// <param name="actionName">Action name</param> 43 /// <param name="controllerName">Controller name</param> 44 /// <param name="routeValues">Route values</param> 45 public void GetConfigurationRoute(out string actionName, out string controllerName, out RouteValueDictionary routeValues) 46 { 47 actionName = "Configure"; 48 controllerName = "WidgetsNivoSlider"; 49 routeValues = new RouteValueDictionary { { "Namespaces", "Nop.Plugin.Widgets.NivoSlider.Controllers" }, { "area", null } }; 50 } 51 52 /// <summary> 53 /// Gets a route for displaying widget 54 /// </summary> 55 /// <param name="widgetZone">Widget zone where it's displayed</param> 56 /// <param name="actionName">Action name</param> 57 /// <param name="controllerName">Controller name</param> 58 /// <param name="routeValues">Route values</param> 59 public void GetDisplayWidgetRoute(string widgetZone, out string actionName, out string controllerName, out RouteValueDictionary routeValues) 60 { 61 actionName = "PublicInfo"; 62 controllerName = "WidgetsNivoSlider"; 63 routeValues = new RouteValueDictionary 64 { 65 {"Namespaces", "Nop.Plugin.Widgets.NivoSlider.Controllers"}, 66 {"area", null}, 67 {"widgetZone", widgetZone} 68 }; 69 } 70 71 /// <summary> 72 /// Install plugin 73 /// </summary> 74 public override void Install() 75 { 76 //pictures 77 var sampleImagesPath = CommonHelper.MapPath("~/Plugins/Widgets.NivoSlider/Content/nivoslider/sample-images/"); 78 79 80 //settings 81 var settings = new NivoSliderSettings 82 { 83 Picture1Id = _pictureService.InsertPicture(File.ReadAllBytes(sampleImagesPath + "banner1.jpg"), MimeTypes.ImagePJpeg, "banner_1").Id, 84 Text1 = "", 85 Link1 = _webHelper.GetStoreLocation(false), 86 Picture2Id = _pictureService.InsertPicture(File.ReadAllBytes(sampleImagesPath + "banner2.jpg"), MimeTypes.ImagePJpeg, "banner_2").Id, 87 Text2 = "", 88 Link2 = _webHelper.GetStoreLocation(false), 89 //Picture3Id = _pictureService.InsertPicture(File.ReadAllBytes(sampleImagesPath + "banner3.jpg"), MimeTypes.ImagePJpeg, "banner_3").Id, 90 //Text3 = "", 91 //Link3 = _webHelper.GetStoreLocation(false), 92 }; 93 _settingService.SaveSetting(settings); 94 95 96 this.AddOrUpdatePluginLocaleResource("Plugins.Widgets.NivoSlider.Picture1", "Picture 1"); 97 this.AddOrUpdatePluginLocaleResource("Plugins.Widgets.NivoSlider.Picture2", "Picture 2"); 98 this.AddOrUpdatePluginLocaleResource("Plugins.Widgets.NivoSlider.Picture3", "Picture 3"); 99 this.AddOrUpdatePluginLocaleResource("Plugins.Widgets.NivoSlider.Picture4", "Picture 4"); 100 this.AddOrUpdatePluginLocaleResource("Plugins.Widgets.NivoSlider.Picture5", "Picture 5"); 101 this.AddOrUpdatePluginLocaleResource("Plugins.Widgets.NivoSlider.Picture", "Picture"); 102 this.AddOrUpdatePluginLocaleResource("Plugins.Widgets.NivoSlider.Picture.Hint", "Upload picture."); 103 this.AddOrUpdatePluginLocaleResource("Plugins.Widgets.NivoSlider.Text", "Comment"); 104 this.AddOrUpdatePluginLocaleResource("Plugins.Widgets.NivoSlider.Text.Hint", "Enter comment for picture. Leave empty if you don't want to display any text."); 105 this.AddOrUpdatePluginLocaleResource("Plugins.Widgets.NivoSlider.Link", "URL"); 106 this.AddOrUpdatePluginLocaleResource("Plugins.Widgets.NivoSlider.Link.Hint", "Enter URL. Leave empty if you don't want this picture to be clickable."); 107 108 base.Install(); 109 } 110 111 /// <summary> 112 /// Uninstall plugin 113 /// </summary> 114 public override void Uninstall() 115 { 116 //settings 117 _settingService.DeleteSetting<NivoSliderSettings>(); 118 119 //locales 120 this.DeletePluginLocaleResource("Plugins.Widgets.NivoSlider.Picture1"); 121 this.DeletePluginLocaleResource("Plugins.Widgets.NivoSlider.Picture2"); 122 this.DeletePluginLocaleResource("Plugins.Widgets.NivoSlider.Picture3"); 123 this.DeletePluginLocaleResource("Plugins.Widgets.NivoSlider.Picture4"); 124 this.DeletePluginLocaleResource("Plugins.Widgets.NivoSlider.Picture5"); 125 this.DeletePluginLocaleResource("Plugins.Widgets.NivoSlider.Picture"); 126 this.DeletePluginLocaleResource("Plugins.Widgets.NivoSlider.Picture.Hint"); 127 this.DeletePluginLocaleResource("Plugins.Widgets.NivoSlider.Text"); 128 this.DeletePluginLocaleResource("Plugins.Widgets.NivoSlider.Text.Hint"); 129 this.DeletePluginLocaleResource("Plugins.Widgets.NivoSlider.Link"); 130 this.DeletePluginLocaleResource("Plugins.Widgets.NivoSlider.Link.Hint"); 131 132 base.Uninstall(); 133 } 134 } 135 } 136Nop.Plugin.Widgets.NivoSlider
在上邊源代碼中我們看到安裝時調用Install()方法進行瞭如下操作
1.定義NivoSliderSettings類,該類繼承ISettings,用於保存幻燈片的配置。將初始化的配置保存到資料庫Setting表中。
2.this.AddOrUpdatePluginLocaleResource方法添加本地資源,主要用於配置資源在多語言支持。
3.base.Install() 進行插件安裝。
卸載插件時調用Uninstall()方法對配置進行刪除,對本地資源進行刪除同時卸載插件。
以上就是在插件安裝、卸載時調用的方法介紹,在二次開發時可在相關時間點進行插件的配置。
三.插件配置路由
不同插件有屬於自己的配置項,例如支付寶插件和微信支付插件同是支付插件但是配置卻不一樣。為了實現不同配置引入了配置路由。小部件IWidgetPlugin介面GetConfigurationRoute方法用於返回配置介面的路由信息。我們看下NivoSlider插件
1 /// <summary> 2 /// Gets a route for provider configuration 3 /// </summary> 4 /// <param name="actionName">Action name</param> 5 /// <param name="controllerName">Controller name</param> 6 /// <param name="routeValues">Route values</param> 7 public void GetConfigurationRoute(out string actionName, out string controllerName, out RouteValueDictionary routeValues) 8 { 9 actionName = "Configure"; 10 controllerName = "WidgetsNivoSlider"; 11 routeValues = new RouteValueDictionary { { "Namespaces", "Nop.Plugin.Widgets.NivoSlider.Controllers" }, { "area", null } }; 12 }
當點擊配置時路由到WidgetsNivoSlider控制器Configure()方法,顯示插件配置頁面
四.多店配置實現
如果配置了兩個以上的商城就會出現上邊的多店設置。可針對不同商店進行不同的配置。
1 [AdminAuthorize] 2 [ChildActionOnly] 3 public ActionResult Configure() 4 { 5 //載入可用商店的範圍 6 var storeScope = this.GetActiveStoreScopeConfiguration(_storeService, _workContext); 7 var nivoSliderSettings = _settingService.LoadSetting<NivoSliderSettings>(storeScope);//載入可用商店的配置 8 var model = new ConfigurationModel(); 9 model.Picture1Id = nivoSliderSettings.Picture1Id; 10 model.Text1 = nivoSliderSettings.Text1; 11 model.Link1 = nivoSliderSettings.Link1; 12 model.Picture2Id = nivoSliderSettings.Picture2Id; 13 model.Text2 = nivoSliderSettings.Text2; 14 model.Link2 = nivoSliderSettings.Link2; 15 model.Picture3Id = nivoSliderSettings.Picture3Id; 16 model.Text3 = nivoSliderSettings.Text3; 17 model.Link3 = nivoSliderSettings.Link3; 18 model.Picture4Id = nivoSliderSettings.Picture4Id; 19 model.Text4 = nivoSliderSettings.Text4; 20 model.Link4 = nivoSliderSettings.Link4; 21 model.Picture5Id = nivoSliderSettings.Picture5Id; 22 model.Text5 = nivoSliderSettings.Text5; 23 model.Link5 = nivoSliderSettings.Link5; 24 model.ActiveStoreScopeConfiguration = storeScope; 25 if (storeScope > 0) 26 { 27 model.Picture1Id_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Picture1Id, storeScope); 28 model.Text1_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Text1, storeScope); 29 model.Link1_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Link1, storeScope); 30 model.Picture2Id_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Picture2Id, storeScope); 31 model.Text2_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Text2, storeScope); 32 model.Link2_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Link2, storeScope); 33 model.Picture3Id_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Picture3Id, storeScope); 34 model.Text3_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Text3, storeScope); 35 model.Link3_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Link3, storeScope); 36 model.Picture4Id_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Picture4Id, storeScope); 37 model.Text4_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Text4, storeScope); 38 model.Link4_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Link4, storeScope); 39 model.Picture5Id_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Picture5Id, storeScope); 40 model.Text5_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Text5, storeScope); 41 model.Link5_OverrideForStore = _settingService.SettingExists(nivoSliderSettings, x => x.Link5, storeScope); 42 } 43 44 return View("~/Plugins/Widgets.NivoSlider/Views/Configure.cshtml", model); 45 }配置源碼
查看源碼我們會發現這兩句是控制多店配置的
1 //載入可用商店的範圍 2 var storeScope = this.GetActiveStoreScopeConfiguration(_storeService, _workContext); 3 var nivoSliderSettings = _settingService.LoadSetting<NivoSliderSettings>(storeScope);//載入可用商店的配置
首先載入當前配置的商店。獲取到 storeScope後載入該商店NivoSliderSetting配置項的設置。
這樣當選擇不同的商城就可以獲取到選擇商城中配置的值了。
我們再來看下Configure.cshtml視圖
@Html.Action("StoreScopeConfiguration", "Setting", new { area = "Admin" })
該路由用於生成nop多店設置模塊,選擇不同商城會調用Setting控制器,ChangeStoreScopeConfiguration方法,該方法會將用戶選擇的商城id 保存在GenericaAttribute表中如下圖。
SystemCustomerAttributeNames.AdminAreaStoreScopeConfiguration變數對應的就是Key值,Velue保存為商城的Id。
當頁面選擇不同的商城時,經過上邊方法的處理,再調用var storeScope = this.GetActiveStoreScopeConfiguration(_storeService, _workContext); 方法就可以獲取到指定的商城了。
當指定商城時我們會發現配置項每一項都多出一個單選框,選擇則可針對該商城的該配置經進行設置,如果不選擇則使用預設項。
在視圖中如何生成這個單選項呢?看下源碼
@Html.OverrideStoreCheckboxFor(model => model.Picture2Id_OverrideForStore, model => model.Picture2Id, Model.ActiveStoreScopeConfiguration)
使用該Html擴展來實現商城配置的定製。OverrideStoreCheckboxFor擴展是Nop.Web.Framework.HtmlExtensions 類中的擴展。
model.Picture2Id_OverrideForStore為True時使用自定義商城配置,model.Picture2Id為配置屬性,model.ActiveStoreScopeConfiguration為當前商城id。
可以看出支持多店配置的model比普通model多出ActiveStoreScopeConfiguration屬性用於保存商城id,同時每個屬性多一個_OverrideForStore的bool方法用於判斷是否覆蓋店鋪預設值。
1 @{ 2 Layout = ""; 3 } 4 @model Nop.Plugin.Widgets.NivoSlider.Models.ConfigurationModel 5 @using Nop.Web.Framework; 6 7 @Html.Action("StoreScopeConfiguration", "Setting", new { area = "Admin" }) 8 9 @using (Html.BeginForm()) 10 { 11 @Html.AntiForgeryToken() 12 <div class="panel-group"> 13 <div class="panel panel-default"> 14 <div class="panel-heading"> 15 @T("Plugins.Widgets.NivoSlider.Picture1") 16 </div> 17 <div class="panel-body"> 18 <div class="form-group"> 19 <div class="col-md-3"> 20 @Html.OverrideStoreCheckboxFor(model => model.Picture1Id_OverrideForStore, model => model.Picture1Id, Model.ActiveStoreScopeConfiguration) 21 @Html.NopLabelFor(model => model.Picture1Id) 22 </div> 23 <div class="col-md-9"> 24 @Html.NopEditorFor(model => model.Picture1Id) 25 @Html.ValidationMessageFor(model => model.Picture1Id) 26 </div> 27 </div> 28 <div class="form-group"> 29 <div class="col-md-3"> 30 @Html.OverrideStoreCheckboxFor(model => model.Text1_OverrideForStore, model => model.Text1, Model.ActiveStoreScopeConfiguration) 31 @Html.NopLabelFor(model => model.Text1) 32 </div> 33 <div class="col-md-9"> 34 @Html.NopEditorFor(model => model.Text1) 35 @Html.ValidationMessageFor(model => model.Text1) 36 </div> 37 </div> 38 <div class="form-group"> 39 <div class="col-md-3"> 40 @Html.OverrideStoreCheckboxFor(model => model.Link1_OverrideForStore, model => model.Link1, Model.ActiveStoreScopeConfiguration) 41 @Html.NopLabelFor(model => model.Link1) 42 </div> 43 <div class="col-md-9"> 44 @Html.NopEditorFor(model => model.Link1) 45 @Html.ValidationMessageFor(model => model.Link1) 46 </div> 47 </div> 48 </div> 49 </div> 50 <div class="panel panel-default"> 51 <div class="panel-heading"> 52 @T("Plugins.Widgets.NivoSlider.Picture2") 53 </div> 54 <div class="panel-body"> 55 <div class="form-group"> 56 <div class="col-md-3"> 57 @Html.OverrideStoreCheckboxFor(model => model.Picture2Id_OverrideForStore, model => model.Picture2Id, Model.ActiveStoreScopeConfiguration) 58 @Html.NopLabelFor(model => model.Picture2Id) 59 </div> 60 <div class="col-md-9"> 61 @Html.NopEditorFor(model => model.Picture2Id) 62 @Html.ValidationMessageFor(model => model.Picture2Id) 63 </div> 64 </div> 65 <div class="form-group"> 66 <div class="col-md-3"> 67 @Html.OverrideStoreCheckboxFor(model => model.Text2_OverrideForStore, model => model.Text2, Model.ActiveStoreScopeConfiguration) 68 @Html.NopLabelFor(model => model.Text2) 69 </div> 70 <div class="col-md-9"> 71 @Html.NopEditorFor(model => model.Text2) 72 @Html.ValidationMessageFor(model => model.Text2) 73 </div> 74 </div> 75 <div class="form-group"> 76 <div class="col-md-3"> 77 @Html.OverrideStoreCheckboxFor(model => model.Link2_OverrideForStore, model => model.Link2, Model.ActiveStoreScopeConfiguration) 78 @Html.NopLabelFor(model => model.Link2) 79 </div> 80 <div class="col-md-9"> 81 @Html.NopEditorFor(model => model.Link2) 82 @Html.ValidationMessageFor(model => model.Link2) 83 </div> 84 </div> 85 </div> 86 </div> 87 <div class="panel panel-default"> 88 <div class="panel-heading"> 89 @T("Plugins.Widgets.NivoSlider.Picture3") 90 </div> 91 <div class="panel-body"> 92 <div class="form-group"> 93 <div class="col-md-3"> 94 @Html.OverrideStoreCheckboxFor(model => model.Picture3Id_OverrideForStore, model => model.Picture3Id, Model.ActiveStoreScopeConfiguration) 95 @Html.NopLabelFor(model => model.Picture3Id) 96 </div> 97 <div class="col-md-9"> 98 @Html.NopEditorFor(model => model.Picture3Id) 99 @Html.ValidationMessageFor(model => model.Picture3Id) 100 </div> 101 </div> 102 <div class="form-group"> 103 <div class="col-md-3"> 104 @Html.OverrideStoreCheckboxFor(model => model.Text3_OverrideForStore, model => model.Text3, Model.ActiveStoreScopeConfiguration) 105 @Html.NopLabelFor(model => model.Text3) 106 </div> 107 <div class="col-md-9"> 108 @Html.NopEditorFor(model => model.Text3) 109 @Html.ValidationMessageFor(model => model.Text3) 110 </div> 111 </div> 112 <div class="form-group"> 113 <div class="col-md-3"> 114 @Html.OverrideStoreCheckboxFor(model => model.Link3_OverrideForStore, model => model.Link3, Model.ActiveStoreScopeConfiguration) 115 @Html.NopLabelFor(model => model.Link3) 116 </div> 117 <div class="col-md-9"> 118 @Html.NopEditorFor(model => model.Link3) 119 @Html.ValidationMessageFor(model => model.Link3) 120 </div> 121 </div> 122 </div> 123 </div> 124 <div class="panel panel-default"> 125 <div class="panel-heading"> 126 @T("Plugins.Widgets.NivoSlider.Picture4") 127 </div> 128 <div class="panel-body"> 129 <div class="form-group"> 130 <div class="col-md-3"> 131 @Html.OverrideStoreCheckboxFor(model => model.Picture4Id_OverrideForStore, model => model.Picture4Id, Model.ActiveStoreScopeConfiguration) 132 @Html.NopLabelFor(model => model.Picture4Id) 133 </div> 134 <div class="col-md-9"> 135 @Html.NopEditorFor(model => model.Picture4Id) 136 @Html.ValidationMessageFor(model => model.Picture4Id) 137 </div> 138 </div> 139 <div class="form-group"> 140 <div class="col-md-3"> 141 @Html.OverrideStoreCheckboxFor(model => model.Text4_OverrideForStore, model => model.Text4, Model.ActiveStoreScopeConfiguration) 142 @Html.NopLabelFor(model => model.Text4) 143 </div> 144 <div class="col-md-9"> 145 @Html.NopEditorFor(model => model.Text4) 146 @Html.ValidationMessageFor(model => model.Text4) 147 </div> 148 </div> 149 <div class="form-group"> 150 <div class="col-md-3"> 151 @Html.OverrideStoreCheckboxFor(model => model.Link4_OverrideForStore, model => model.Link4, Model.ActiveStoreScopeConfiguration) 152 @Html.NopLabelFor(model => model.Link4) 153 </div> 154 <div class="col-md-9"> 155 @Html.NopEditorFor(model => model.Link4) 156 @Html.ValidationMessageFor(model => model.Link4) 157 </div> 158 </div> 159 </div> 160 </div> 161 <div class="panel panel-default"> 162 <div class="panel-heading"> 163 @T("Plugins.Widgets.NivoSlider.Picture5") 164 </div> 165 <div class="panel-body"> 166 <div class="form-group"> 167 <div class="col-md-3"> 168 @Html.OverrideStoreCheckboxFor(model => model.Picture5Id_OverrideForStore, model => model.Picture5Id, Model.ActiveStoreScopeConfiguration) 169 @Html.NopLabelFor(model => model.Picture5Id) 170 </div> 171 <div class="col-md-9"> 172 @Html.NopEditorFor(model => model.Picture5Id) 173 @Html.ValidationMessageFor(model => model.Picture5Id) 174 </div> 175 </div> 176 <div class="form-group"> 177 <div class="col-md-3"> 178 @Html.OverrideStoreCheckboxFor(model => model.Text5_OverrideForStore, model => model.Text5, Model.ActiveStoreScopeConfiguration) 179 @Html.NopLabelFor(model => model.Text5) 180 </div> 181 <div class="col-md-9"> 182 @Html.NopEditorFor(model => model.Text5) 183 @Html.ValidationMessageFor(model => model.Text5) 184 </div> 185 </div> 186 <div class="form-group"> 187 <div class="col-md-3"> 188 @Html.OverrideStoreCheckboxFor(model => model.Link5_OverrideForStore, model => model.Link5, Model.ActiveStoreScopeConfiguration) 189 @Html.NopLabelFor(model => model.Link5) 190 </div> 191 <div class="col-md-9"> 192 @Html.NopEditorFor(model => model.Link5) 193 @Html.ValidationMessageFor(model => model.Link5) 194 </div> 195 </div> 196 </div> 197 </div> 198 <div class="panel panel-default">