nopCommerce 3.9 大波浪系列 之 路由扩展 [多语言Seo的实现]
Posted 大波浪 要上进
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nopCommerce 3.9 大波浪系列 之 路由扩展 [多语言Seo的实现]相关的知识,希望对你有一定的参考价值。
一.nop中的路由注册
在Global.asax,Application_Start()方法中会进行路由注册,代码如下。
1 public static void RegisterRoutes(RouteCollection routes) 2 { 3 routes.IgnoreRoute("favicon.ico"); 4 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 5 6 //register custom routes (plugins, etc) 7 var routePublisher = EngineContext.Current.Resolve<IRoutePublisher>(); 8 routePublisher.RegisterRoutes(routes); 9 10 routes.MapRoute( 11 "Default", // Route name 12 "{controller}/{action}/{id}", // URL with parameters 13 new { controller = "Home", action = "Index", id = UrlParameter.Optional }, 14 new[] { "Nop.Web.Controllers" } 15 ); 16 }
我们会发现调用了IRutePublisher接口,该接口由Nop.Web.Framework.Mvc.Routes.RoutePublisher类实现。
并通过RegisterRoutes(RouteCollection routes)方法进行路由注册。代码如下:
1 /// <summary> 2 /// Register routes 3 /// </summary> 4 /// <param name="routes">Routes</param> 5 public virtual void RegisterRoutes(RouteCollection routes) 6 { 7 //ITypeFinder接口获取所有IRouteProvider接口实现类的Type对象 8 var routeProviderTypes = typeFinder.FindClassesOfType<IRouteProvider>(); 9 var routeProviders = new List<IRouteProvider>(); 10 foreach (var providerType in routeProviderTypes) 11 { 12 //Ignore not installed plugins 13 var plugin = FindPlugin(providerType);//PluginManager.ReferencedPlugins中查找该Type对象 14 if (plugin != null && !plugin.Installed)//插件不为空未安装则跳出本次循环 15 continue; 16 17 var provider = Activator.CreateInstance(providerType) as IRouteProvider;//实例化IRouteProvider接口对象 18 routeProviders.Add(provider); 19 } 20 routeProviders = routeProviders.OrderByDescending(rp => rp.Priority).ToList();//排序 21 routeProviders.ForEach(rp => rp.RegisterRoutes(routes));//遍历并调用RegisterRoutes(routes)进行路由注册 22 }
该方法做了如下工作:
第一步:通过ITyperFinder接口找到所有实现了IRouteProvider接口的类类型。保存在routeProviderTypes集合中
第二步:遍历routeProviderTypes集合,通过PluginManager类找到未安装IRouteProvider类类型。并从routeProviderTypes集合中排除掉。
第三步:实例化IRouteProvider实现类。
第四步:调用IRouteProvider实现类RegisterRoutes(routes)方法进行路由注册。
下图为主要接口之间的调用关系
通过上述分析nop路由注册主要是通过IRouteProvider接口实现的,现在我们看看项目中实现该接口的类都有哪些。
下图红色是在Nop.Web项目中,其他都是在nop插件中。
接下来我们看下路由的注册顺序如下图,我们看到最先匹配的Nop.Web.Infrastructure.RouteProvider中的路由注册。
二.启用支持多语言的SEO友好链接
nop支持SEO友好链接,管理后台->设置管理->综合设置->启用支持多语言的SEO友好链接 选中就可以支持了。
启用后URL格式为: http://www.yourStore.com/en/ 或 http://www.yourStore.com/zh/ (SEO比较友好)
那该功能怎么实现的呢?接下来我们看看nop是如何通过路由扩展实现的。
(Nop.Web.Framework.WebWorkContext在多语言中也会用到,这里先不讲它,我们只说路由)
我们先看下Nop.Web.Infrastructure.RouteProvider中的路由注册代码
1 using System.Web.Mvc; 2 using System.Web.Routing; 3 using Nop.Web.Framework.Localization; 4 using Nop.Web.Framework.Mvc.Routes; 5 6 namespace Nop.Web.Infrastructure 7 { 8 public partial class RouteProvider : IRouteProvider 9 { 10 public void RegisterRoutes(RouteCollection routes) 11 { 12 //We reordered our routes so the most used ones are on top. It can improve performance. 13 //本地化路由 14 //home page 15 routes.MapLocalizedRoute("HomePage", 16 "", 17 new { controller = "Home", action = "Index" }, 18 new[] { "Nop.Web.Controllers" }); 19 //widgets 20 //we have this route for performance optimization because named routes are MUCH faster than usual html.Action(...) 21 //and this route is highly used 22 routes.MapRoute("WidgetsByZone", 23 "widgetsbyzone/", 24 new { controller = "Widget", action = "WidgetsByZone" }, 25 new[] { "Nop.Web.Controllers" }); 26 27 //login 28 routes.MapLocalizedRoute("Login", 29 "login/", 30 new { controller = "Customer", action = "Login" }, 31 new[] { "Nop.Web.Controllers" }); 32 //register 33 routes.MapLocalizedRoute("Register", 34 "register/", 35 new { controller = "Customer", action = "Register" }, 36 new[] { "Nop.Web.Controllers" }); 37 //logout 38 routes.MapLocalizedRoute("Logout", 39 "logout/", 40 new { controller = "Customer", action = "Logout" }, 41 new[] { "Nop.Web.Controllers" }); 42 43 //shopping cart 44 routes.MapLocalizedRoute("ShoppingCart", 45 "cart/", 46 new { controller = "ShoppingCart", action = "Cart" }, 47 new[] { "Nop.Web.Controllers" }); 48 //estimate shipping 49 routes.MapLocalizedRoute("EstimateShipping", 50 "cart/estimateshipping", 51 new {controller = "ShoppingCart", action = "GetEstimateShipping"}, 52 new[] {"Nop.Web.Controllers"}); 53 //wishlist 54 routes.MapLocalizedRoute("Wishlist", 55 "wishlist/{customerGuid}", 56 new { controller = "ShoppingCart", action = "Wishlist", customerGuid = UrlParameter.Optional }, 57 new[] { "Nop.Web.Controllers" }); 58 59 //customer account links 60 routes.MapLocalizedRoute("CustomerInfo", 61 "customer/info", 62 new { controller = "Customer", action = "Info" }, 63 new[] { "Nop.Web.Controllers" }); 64 routes.MapLocalizedRoute("CustomerAddresses", 65 "customer/addresses", 66 new { controller = "Customer", action = "Addresses" }, 67 new[] { "Nop.Web.Controllers" }); 68 routes.MapLocalizedRoute("CustomerOrders", 69 "order/history", 70 new { controller = "Order", action = "CustomerOrders" }, 71 new[] { "Nop.Web.Controllers" }); 72 73 //contact us 74 routes.MapLocalizedRoute("ContactUs", 75 "contactus", 76 new { controller = "Common", action = "ContactUs" }, 77 new[] { "Nop.Web.Controllers" }); 78 //sitemap 79 routes.MapLocalizedRoute("Sitemap", 80 "sitemap", 81 new { controller = "Common", action = "Sitemap" }, 82 new[] { "Nop.Web.Controllers" }); 83 84 //product search 85 routes.MapLocalizedRoute("ProductSearch", 86 "search/", 87 new { controller = "Catalog", action = "Search" }, 88 new[] { "Nop.Web.Controllers" }); 89 routes.MapLocalizedRoute("ProductSearchAutoComplete", 90 "catalog/searchtermautocomplete", 91 new { controller = "Catalog", action = "SearchTermAutoComplete" }, 92 new[] { "Nop.Web.Controllers" }); 93 94 //change currency (AJAX link) 95 routes.MapLocalizedRoute("ChangeCurrency", 96 "changecurrency/{customercurrency}", 97 new { controller = "Common", action = "SetCurrency" }, 98 new { customercurrency = @"\\d+" }, 99 new[] { "Nop.Web.Controllers" }); 100 //change language (AJAX link) 101 routes.MapLocalizedRoute("ChangeLanguage", 102 "changelanguage/{langid}", 103 new { controller = "Common", action = "SetLanguage" }, 104 new { langid = @"\\d+" }, 105 new[] { "Nop.Web.Controllers" }); 106 //change tax (AJAX link) 107 routes.MapLocalizedRoute("ChangeTaxType", 108 "changetaxtype/{customertaxtype}", 109 new { controller = "Common", action = "SetTaxType" }, 110 new { customertaxtype = @"\\d+" }, 111 new[] { "Nop.Web.Controllers" }); 112 113 //recently viewed products 114 routes.MapLocalizedRoute("RecentlyViewedProducts", 115 "recentlyviewedproducts/", 116 new { controller = "Product", action = "RecentlyViewedProducts" }, 117 new[] { "Nop.Web.Controllers" }); 118 //new products 119 routes.MapLocalizedRoute("NewProducts", 120 "newproducts/", 121 new { controller = "Product", action = "NewProducts" }, 122 new[] { "Nop.Web.Controllers" }); 123 //blog 124 routes.MapLocalizedRoute("Blog", 125 "blog", 126 new { controller = "Blog", action = "List" }, 127 new[] { "Nop.Web.Controllers" }); 128 //news 129 routes.MapLocalizedRoute("NewsArchive", 130 "news", 131 new { controller = "News", action = "List" }, 132 new[] { "Nop.Web.Controllers" }); 133 134 //forum 135 routes.MapLocalizedRoute("Boards", 136 "boards", 137 new { controller = "Boards", action = "Index" }, 138 new[] { "Nop.Web.Controllers" }); 139 140 //compare products 141 routes.MapLocalizedRoute("CompareProducts", 142 "compareproducts/", 143 new { controller = "Product", action = "CompareProducts" }, 144 new[] { "Nop.Web.Controllers" }); 145 146 //product tags 147 routes.MapLocalizedRoute("ProductTagsAll", 148 "producttag/all/", 149 new { controller = "Catalog", action = "ProductTagsAll" }, 150 new[] { "Nop.Web.Controllers" }); 151 152 //manufacturers 153 routes.MapLocalizedRoute("ManufacturerList", 154 "manufacturer/all/", 155 new { controller = "Catalog", action = "ManufacturerAll" }, 156 new[] { "Nop.Web.Controllers" }); 157 //vendors 158 routes.MapLocalizedRoute("VendorList", 159 "vendor/all/", 160 new { controller = "Catalog", action = "VendorAll" }, 161 new[] { "Nop.Web.Controllers" }); 162 163 164 //add product to cart (without any attributes and options). used on catalog pages. 165 routes.MapLocalizedRoute("AddProductToCart-Catalog", 166 "addproducttocart/catalog/{productId}/{shoppingCartTypeId}/{quantity}", 167 new { controller = "ShoppingCart", action = "AddProductToCart_Catalog" }, 168 new { productId = @"\\d+", shoppingCartTypeId = @"\\d+", quantity = @"\\d+" }, 169 new[] { "Nop.Web.Controllers" }); 170 //add product to cart (with attributes and options). used on the product details pages. 171 routes.MapLocalizedRoute("AddProductToCart-Details", 172 "addproducttocart/details/{productId}/{shoppingCartTypeId}", 173 new { controller = "ShoppingCart", action = "AddProductToCart_Details" }, 174 new { productId = @"\\d+", shoppingCartTypeId = @"\\d+" }, 175 new[] { "Nop.Web.Controllers" }); 176 177 //product tags 178 routes.MapLocalizedRoute("ProductsByTag", 179 "producttag/{productTagId}/{SeName}", 180 new { controller = "Catalog", action = "ProductsByTag", SeName = UrlParameter.Optional }, 181 new { productTagId = @"\\d+" }, 182 new[] { "Nop.Web.Controllers" }); 183 //comparing products 184 routes.MapLocalizedRoute("AddProductToCompare", 185 "compareproducts/add/{productId}", 186 new { controller = "Product", action = "AddProductToCompareList" }, 187 new { productId = @"\\d+" }, 188 new[] { "Nop.Web.Controllers" }); 189 //product email a friend 190 routes.MapLocalizedRoute("ProductEmailAFriend", 191 "productemailafriend/{productId}", 192 new { controller = "Product", action = "ProductEmailAFriend" }, 193 new { productId = @"\\d+" }, 194 new[] { "Nop.Web.Controllers" }); 195 //reviews 196 routes.MapLocalizedRoute("ProductReviews", 197 "productreviews/{productId}", 198 new { controller = "Product", action = "ProductReviews" }, 199 new[] { "Nop.Web.Controllers" }); 200 routes.MapLocalizedRoute("CustomerProductReviews", 201 "customer/productreviews", 202 new { controller = "Product", action = "CustomerProductReviews" }, 203 new[] { "Nop.Web.Controllers" }); 204 routes.MapLocalizedRoute("CustomerProductReviewsPaged", 205 "customer/productreviews/page/{page}", 206 new { controller = "Product", action = "CustomerProductReviews" }, 207 new { page = @"\\d+" }, 208 new[] { "Nop.Web.Controllers" }); 209 //back in stock notifications 210 routes.MapLocalizedRoute("BackInStockSubscribePopup", 211 "backinstocksubscribe/{productId}", 212 new { controller = "BackInStockSubscription", action = "SubscribePopup" }, 213 new { productId = @"\\d+" }, 214 new[] { "Nop.Web.Controllers" }); 215 routes.MapLocalizedRoute("BackInStockSubscribeSend", 216 "backinstocksubscribesend/{productId}", 217 new { controller = "BackInStockSubscription", action = "SubscribePopupPOST" }, 218 new { productId = @"\\d+" }, 219 new[] { "Nop.Web.Controllers" }); 220 //downloads 221 routes.MapRoute("GetSampleDownload", 222 "download/sample/{productid}", 223 new { controller = "Download", action = "Sample" }, 224 new { productid = @"\\d+" }, 225 new[] { "Nop.Web.Controllers" }); 226 227 228 229 //checkout pages 230 routes.MapLocalizedRoute("Checkout", 231 "checkout/", 232 new { controller = "Checkout", action = "Index" }, 233 new[] { "Nop.Web.Controllers" }); 234 routes.MapLocalizedRoute("CheckoutOnePage", 235 "onepagecheckout/", 236 new { controller = "Checkout", action = "OnePageCheckout" }, 237 new[] { "Nop.Web.Controllers" }); 238 routes.MapLocalizedRoute("CheckoutShippingAddress", 239 "checkout/shippingaddress", 240 new { controller = "Checkout", action = "ShippingAddress" }, 241 new[] { "Nop.Web.Controllers" }); 242 routes.MapLocalizedRoute("CheckoutSelectShippingAddress", 243 "checkout/selectshippingaddress", 244 new { controller = "Checkout", action = "SelectShippingAddress" }, 245 new[] { "Nop.Web.Controllers" }); 246 routes.MapLocalizedRoute("CheckoutBillingAddress", 247 "checkout/billingaddress", 248 new { controller = "Checkout", action = "BillingAddress" }, 249 new[] { "Nop.Web.Controllers" }); 250 routes.MapLocalizedRoute("CheckoutSelectBillingAddress", 251 "checkout/selectbillingaddress", 252 new { controller = "Checkout", action = "SelectBillingAddress" }, 253 new[] { "Nop.Web.Controllers" }); 254 routes.MapLocalizedRoute("CheckoutShippingMethod", 255 "checkout/shippingmethod", 256 new { controller = "Checkout", action = "ShippingMethod" }, 257 new[] { "Nop.Web.Controllers" }); 258 routes.MapLocalizedRoute("CheckoutPaymentMethod", 259 "checkout/paymentmethod", 260 new { controller = "Checkout", action = "PaymentMethod" }, 261 new[] { "Nop.Web.Controllers" }); 262 routes.MapLocalizedRoute("CheckoutPaymentInfo", 263 "checkout/paymentinfo", 264 new { controller = "Checkout", action = "PaymentInfo" }, 265 new[] { "Nop.Web.Controllers" }); 266 routes.MapLocalizedRoute("CheckoutConfirm", 267 "checkout/confirm", 268 new { controller = "Checkout", action = "Confirm" }, 269 new[] { "Nop.Web.Controllers" }); 270 routes.MapLocalizedRoute("CheckoutCompleted", 271 "checkout/completed/{orderId}", 272 new { controller = "Checkout", action = "Completed", orderId = UrlParameter.Optional }, 273 new { orderId = @"\\d+" }, 274 new[] { "Nop.Web.Controllers" }); 275 276 //subscribe newsletters 277 routes.MapLocalizedRoute("SubscribeNewsletter", 278 "subscribenewsletter", 279 new { controller = "Newsletter", action = "SubscribeNewsletter" }, 280 new[] { "Nop.Web.Controllers" }); 281 282 //email wishlist 283 routes.MapLocalizedRoute("EmailWishlist", 284 "emailwishlist", 285 new { controller = "ShoppingCart", action = "EmailWishlist" }, 286 new[] { "Nop.Web.Controllers" }); 287 288 //login page for checkout as guest 289 routes.MapLocalizedRoute("LoginCheckoutAsGuest", 290 "login/checkoutasguest", 291 new { controller = "Customer", action = "Login", checkoutAsGuest = true }, 292 new[] { "Nop.Web.Controllers" }); 293 //register result page 294 routes.MapLocalizedRoute("RegisterResult", 295 "registerresult/{resultId}", 296 new { controller = "Customer", action = "RegisterResult" }, 297 new { resultId = @"\\d+" }, 298 new[] { "Nop.Web.Controllers" }); 299 //check username availability 300 routes.MapLocalizedRoute("CheckUsernameAvailability", 301 "customer/checkusernameavailability", 302 new { controller = "Customer", action = "CheckUsernameAvailability" }, 303 new[] { "Nop.Web.Controllers" }); 304 305 //passwordrecovery 306 routes.MapLocalizedRoute("PasswordRecovery", 307 "passwordrecovery", 308 new { controller = "Customer", action = "PasswordRecovery" }, 309 new[] { "Nop.Web.Controllers" }); 310 //password recovery confirmation 311 routes.MapLocalizedRoute("PasswordRecoveryConfirm", nopCommerce 3.9 大波浪系列 之 汉化-Roxy FilemannopCommerce 3.9 大波浪系列 之 global.asax
nopCommerce 3.9 大波浪系列 之 路由扩展 [多语言Seo的实现]
nopCommerce 3.9 大波浪系列 之 路由扩展 [多语言Seo的实现]