using Microsoft.AspNetCore.Mvc.Razor; using Nop.Core.Infrastructure; namespace Nop.Web.Framework.Themes; /// /// Specifies the contracts for a view location expander that is used by Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine instances to determine search paths for a view. /// public partial class ThemeableViewLocationExpander : IViewLocationExpander { protected const string THEME_KEY = "nop.themename"; /// /// Invoked by a Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine to determine the /// values that would be consumed by this instance of Microsoft.AspNetCore.Mvc.Razor.IViewLocationExpander. /// The calculated values are used to determine if the view location has changed since the last time it was located. /// /// Context public void PopulateValues(ViewLocationExpanderContext context) { //no need to add the themeable view locations at all as the administration should not be themeable anyway if (context.AreaName?.Equals(AreaNames.ADMIN) ?? false) return; context.Values[THEME_KEY] = EngineContext.Current.Resolve().GetWorkingThemeNameAsync().Result; } /// /// Invoked by a Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine to determine potential locations for a view. /// /// Context /// View locations /// View locations public IEnumerable ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable viewLocations) { if (context.Values.TryGetValue(THEME_KEY, out string theme)) { viewLocations = new[] { $"/Themes/{theme}/Views/{{1}}/{{0}}.cshtml", $"/Themes/{theme}/Views/Shared/{{0}}.cshtml", } .Concat(viewLocations); } return viewLocations; } }