NopCommerce 根据手机浏览器和桌面浏览器切换 Theme
自从 NopCommerce 升级到 3.x 以来,默认的 ViewName.Mobile.cshtml 方式就被响应式的默认 Theme 取代了。
但是在今天各种手机专用前端库大行其道的情况下,响应式主题在手机端上的体验并不好,与专门制作的手机版页面相比显得傻大笨粗。所以如果是一个投入比较大的 NopCommerce 电商网站,比较完美的办法是同时制作 PC 和手机网站 Theme,然后依据用户浏览时所使用的浏览器自动切换。
实现 NopCommerce Theme 依据用户浏览器自动切换需要对 NopCommerce 的代码做如下修改(基于 NopCommerce 3.7):
1. 为 UserAgentHelper 增加判断是否移动设备的方法
修改 Nop.Services.Helpers.IUserAgentHelper 接口添加如下方法声明:
bool IsMobileDevice();
修改 Nop.Services.Helpers.UserAgentHelper 类添加 IsMobileDevice() 方法的实现代码:
public virtual bool IsMobileDevice() { bool isTablet = false; if (bool.TryParse(_httpContext.Request.Browser["IsTablet"], out isTablet) && isTablet) { return false; } var userAgent = _httpContext.Request.UserAgent.ToLowerInvariant(); //微信浏览器的 UA 为 “micromessenger” if (_httpContext.Request.Browser.IsMobileDevice || userAgent.Contains("micromessenger")) { return true; } return false; }
2. 修改 ThemeContext 类添加主题根据是否移动浏览器切换的功能:
以下是完整的修改后 Nop.Web.Framework.Themes.ThemeContext 类:
using System; using System.Linq; using Nop.Core; using Nop.Core.Domain; using Nop.Core.Domain.Customers; using Nop.Services.Common; using Nop.Services.Helpers; namespace Nop.Web.Framework.Themes { /// <summary> /// Theme context /// </summary> public partial class ThemeContext : IThemeContext { private readonly IWorkContext _workContext; private readonly IStoreContext _storeContext; private readonly IGenericAttributeService _genericAttributeService; private readonly StoreInformationSettings _storeInformationSettings; private readonly IThemeProvider _themeProvider; private readonly IUserAgentHelper _userAgentHelper; private bool _themeIsCached; private string _cachedThemeName; public ThemeContext(IWorkContext workContext, IStoreContext storeContext, IGenericAttributeService genericAttributeService, StoreInformationSettings storeInformationSettings, IUserAgentHelper userAgentHelper, IThemeProvider themeProvider) { this._workContext = workContext; this._storeContext = storeContext; this._genericAttributeService = genericAttributeService; this._storeInformationSettings = storeInformationSettings; this._themeProvider = themeProvider; this._userAgentHelper = userAgentHelper; } /// <summary> /// Get or set current theme system name /// </summary> public string WorkingThemeName { get { if (_themeIsCached) return _cachedThemeName; string theme = ""; /* if (_storeInformationSettings.AllowCustomerToSelectTheme) { if (_workContext.CurrentCustomer != null) theme = _workContext.CurrentCustomer.GetAttribute<string>(SystemCustomerAttributeNames.WorkingThemeName, _genericAttributeService, _storeContext.CurrentStore.Id); } */ if (this._userAgentHelper.IsMobileDevice()) { theme = "你的手机版 Theme 名称"; }//default store theme if (string.IsNullOrEmpty(theme)) theme = _storeInformationSettings.DefaultStoreTheme; //ensure that theme exists if (!_themeProvider.ThemeConfigurationExists(theme)) { var themeInstance = _themeProvider.GetThemeConfigurations() .FirstOrDefault(); if (themeInstance == null) throw new Exception("No theme could be loaded"); theme = themeInstance.ThemeName; } //cache theme this._cachedThemeName = theme; this._themeIsCached = true; return theme; } set { if (!_storeInformationSettings.AllowCustomerToSelectTheme) return; if (_workContext.CurrentCustomer == null) return; _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer, SystemCustomerAttributeNames.WorkingThemeName, value, _storeContext.CurrentStore.Id); //clear cache this._themeIsCached = false; } } } }
注意代码中
theme = "你的手机版 Theme 名称";
一行,这里的字符串修改为你的手机 Theme 的名称,也就是 Theme 的文件夹名。
修改完成以后,默认的桌面浏览器 Theme 将使用后台设置的主题,一旦检测到移动浏览器则使用代码里手机浏览器 Theme。
这里我们把手机 Theme 名称写死了,当然更好的办法是修改后台增加一个手机 Theme 的设置,不过那个需要修改的就代码就比较多了,各位读者可以自行实现。