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 的设置,不过那个需要修改的就代码就比较多了,各位读者可以自行实现。

原文地址:https://www.cnblogs.com/oldrev/p/5243819.html