mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-07-17 07:22:55 +08:00
Further incremental work establishing a per-request theme-aware engine stack
--HG-- extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4044110
This commit is contained in:
parent
341bb208b0
commit
7b777ef4f6
@ -91,6 +91,7 @@
|
||||
<Compile Include="Themes\Permissions.cs" />
|
||||
<Compile Include="Themes\Records\ThemeRecord.cs" />
|
||||
<Compile Include="Themes\Records\ThemeSiteSettingsRecord.cs" />
|
||||
<Compile Include="Themes\Services\SiteThemeSelector.cs" />
|
||||
<Compile Include="Themes\Services\ThemeService.cs" />
|
||||
<Compile Include="Themes\ViewModels\ThemesIndexViewModel.cs" />
|
||||
<Compile Include="XmlRpc\Controllers\HomeController.cs" />
|
||||
|
@ -28,7 +28,7 @@ namespace Orchard.Core.Themes.Controllers {
|
||||
public ActionResult Index() {
|
||||
try {
|
||||
var themes = _themeService.GetInstalledThemes();
|
||||
var currentTheme = _themeService.GetCurrentTheme();
|
||||
var currentTheme = _themeService.GetSiteTheme();
|
||||
var model = new ThemesIndexViewModel { CurrentTheme = currentTheme, Themes = themes };
|
||||
return View(model);
|
||||
}
|
||||
@ -40,9 +40,9 @@ namespace Orchard.Core.Themes.Controllers {
|
||||
|
||||
public ActionResult Activate(string themeName) {
|
||||
try {
|
||||
if (!_authorizer.Authorize(Permissions.SetCurrentTheme, T("Couldn't set the current theme")))
|
||||
if (!_authorizer.Authorize(Permissions.SetSiteTheme, T("Couldn't set the current theme")))
|
||||
return new HttpUnauthorizedResult();
|
||||
_themeService.SetCurrentTheme(themeName);
|
||||
_themeService.SetSiteTheme(themeName);
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
catch (Exception exception) {
|
||||
|
@ -4,7 +4,7 @@ using Orchard.Security.Permissions;
|
||||
namespace Orchard.Core.Themes {
|
||||
public class Permissions : IPermissionProvider {
|
||||
public static readonly Permission InstallUninstallTheme = new Permission { Description = "Installing or Uninstalling Themes", Name = "InstallUninstallTheme" };
|
||||
public static readonly Permission SetCurrentTheme = new Permission { Description = "Setting the Current Theme", Name = "SetCurrentTheme" };
|
||||
public static readonly Permission SetSiteTheme = new Permission { Description = "Setting the Current Theme", Name = "SetSiteTheme" };
|
||||
|
||||
public string PackageName {
|
||||
get {
|
||||
@ -14,7 +14,7 @@ namespace Orchard.Core.Themes {
|
||||
|
||||
public IEnumerable<Permission> GetPermissions() {
|
||||
return new List<Permission> {
|
||||
SetCurrentTheme,
|
||||
SetSiteTheme,
|
||||
InstallUninstallTheme
|
||||
};
|
||||
}
|
||||
|
28
src/Orchard.Web/Core/Themes/Services/SiteThemeSelector.cs
Normal file
28
src/Orchard.Web/Core/Themes/Services/SiteThemeSelector.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
using Orchard.Core.Themes.Models;
|
||||
using Orchard.Models;
|
||||
using Orchard.Settings;
|
||||
using Orchard.Themes;
|
||||
|
||||
namespace Orchard.Core.Themes.Services {
|
||||
public class SiteThemeSelector : IThemeSelector {
|
||||
private readonly IThemeService _themeService;
|
||||
|
||||
public SiteThemeSelector (IThemeService themeService) {
|
||||
_themeService = themeService;
|
||||
}
|
||||
|
||||
|
||||
public ThemeSelectorResult GetTheme(RequestContext context) {
|
||||
var theme = _themeService.GetSiteTheme();
|
||||
if (theme == null) {
|
||||
return null;
|
||||
}
|
||||
return new ThemeSelectorResult {Priority = -5, ThemeName = theme.ThemeName};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
using Orchard.Extensions;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Models;
|
||||
@ -11,9 +13,13 @@ using Orchard.Core.Themes.Models;
|
||||
namespace Orchard.Core.Themes.Services {
|
||||
public class ThemeService : IThemeService {
|
||||
private readonly IExtensionManager _extensionManager;
|
||||
private readonly IEnumerable<IThemeSelector> _themeSelectors;
|
||||
|
||||
public ThemeService(IExtensionManager extensionManager) {
|
||||
public ThemeService(
|
||||
IExtensionManager extensionManager,
|
||||
IEnumerable<IThemeSelector> themeSelectors) {
|
||||
_extensionManager = extensionManager;
|
||||
_themeSelectors = themeSelectors;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
@ -22,7 +28,7 @@ namespace Orchard.Core.Themes.Services {
|
||||
|
||||
#region Implementation of IThemeService
|
||||
|
||||
public ITheme GetCurrentTheme() {
|
||||
public ITheme GetSiteTheme() {
|
||||
string currentThemeName = CurrentSite.As<ThemeSiteSettings>().Record.CurrentThemeName;
|
||||
|
||||
if (String.IsNullOrEmpty(currentThemeName)) {
|
||||
@ -32,6 +38,27 @@ namespace Orchard.Core.Themes.Services {
|
||||
return GetThemeByName(currentThemeName);
|
||||
}
|
||||
|
||||
public void SetSiteTheme(string themeName) {
|
||||
if (GetThemeByName(themeName) != null) {
|
||||
CurrentSite.As<ThemeSiteSettings>().Record.CurrentThemeName = themeName;
|
||||
}
|
||||
}
|
||||
|
||||
public ITheme GetRequestTheme(RequestContext requestContext) {
|
||||
|
||||
var requestTheme = _themeSelectors
|
||||
.Select(x => x.GetTheme(requestContext))
|
||||
.Where(x => x != null)
|
||||
.OrderByDescending(x => x.Priority)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (requestTheme == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return GetThemeByName(requestTheme.ThemeName);
|
||||
}
|
||||
|
||||
public ITheme GetThemeByName(string name) {
|
||||
foreach (var descriptor in _extensionManager.AvailableExtensions()) {
|
||||
if (String.Equals(descriptor.Name, name, StringComparison.OrdinalIgnoreCase)) {
|
||||
@ -66,11 +93,6 @@ namespace Orchard.Core.Themes.Services {
|
||||
return themes;
|
||||
}
|
||||
|
||||
public void SetCurrentTheme(string themeName) {
|
||||
if (GetThemeByName(themeName) != null) {
|
||||
CurrentSite.As<ThemeSiteSettings>().Record.CurrentThemeName = themeName;
|
||||
}
|
||||
}
|
||||
|
||||
public void InstallTheme(HttpPostedFileBase file) {
|
||||
_extensionManager.InstallExtension("Theme", file);
|
||||
|
@ -1,7 +1,18 @@
|
||||
namespace Orchard.Extensions {
|
||||
public class ExtensionDescriptor {
|
||||
/// <summary>
|
||||
/// Virtual path base, "~/Themes", "~/Packages", or "~/Core"
|
||||
/// </summary>
|
||||
public string Location { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Folder name under virtual path base
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// "Theme" or "Package"
|
||||
/// </summary>
|
||||
public string ExtensionType { get; set; }
|
||||
|
||||
// extension metadata
|
||||
|
@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Mvc.ViewEngines;
|
||||
|
||||
namespace Orchard.Mvc.Html {
|
||||
|
17
src/Orchard/Mvc/ViewEngines/IViewEngineProvider.cs
Normal file
17
src/Orchard/Mvc/ViewEngines/IViewEngineProvider.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Orchard.Mvc.ViewEngines {
|
||||
public class CreateThemeViewEngineParams {
|
||||
public string VirtualPath { get; set; }
|
||||
}
|
||||
|
||||
public class CreatePackagesViewEngineParams {
|
||||
public IEnumerable<string> VirtualPaths { get; set; }
|
||||
}
|
||||
|
||||
public interface IViewEngineProvider : IDependency {
|
||||
IViewEngine CreateThemeViewEngine(CreateThemeViewEngineParams parameters);
|
||||
IViewEngine CreatePackagesViewEngine(CreatePackagesViewEngineParams parameters);
|
||||
}
|
||||
}
|
66
src/Orchard/Mvc/ViewEngines/ViewEngineFilter.cs
Normal file
66
src/Orchard/Mvc/ViewEngines/ViewEngineFilter.cs
Normal file
@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Extensions;
|
||||
using Orchard.Mvc.Filters;
|
||||
using Orchard.Themes;
|
||||
|
||||
namespace Orchard.Mvc.ViewEngines {
|
||||
|
||||
//TEMP: abstract only because it's not functional yet
|
||||
public abstract class ViewEngineFilter : FilterProvider, IResultFilter {
|
||||
private readonly ViewEngineCollection _viewEngines;
|
||||
private readonly IThemeService _themeService;
|
||||
private readonly IExtensionManager _extensionManager;
|
||||
private readonly IEnumerable<IViewEngineProvider> _viewEngineProviders;
|
||||
|
||||
public ViewEngineFilter(
|
||||
ViewEngineCollection viewEngines,
|
||||
IThemeService themeService,
|
||||
IExtensionManager extensionManager,
|
||||
IEnumerable<IViewEngineProvider> viewEngineProviders) {
|
||||
_viewEngines = viewEngines;
|
||||
_themeService = themeService;
|
||||
_extensionManager = extensionManager;
|
||||
_viewEngineProviders = viewEngineProviders;
|
||||
}
|
||||
|
||||
public void OnResultExecuting(ResultExecutingContext filterContext) {
|
||||
var viewResultBase = filterContext.Result as ViewResultBase;
|
||||
if (viewResultBase == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO: factor out into a service apart from the filter
|
||||
|
||||
var requestTheme = _themeService.GetRequestTheme(filterContext.RequestContext);
|
||||
|
||||
var theme = _extensionManager.ActiveExtensions()
|
||||
.Single(x => x.Descriptor.ExtensionType == "Theme" && x.Descriptor.Name == requestTheme.ThemeName);
|
||||
|
||||
var themeLocation = Path.Combine(theme.Descriptor.Location, theme.Descriptor.Name);
|
||||
|
||||
var themeViewEngines = _viewEngineProviders
|
||||
.Select(x => x.CreateThemeViewEngine(new CreateThemeViewEngineParams{VirtualPath = themeLocation}));
|
||||
|
||||
var packages = _extensionManager.ActiveExtensions()
|
||||
.Where(x => x.Descriptor.ExtensionType == "Package");
|
||||
|
||||
var packageLocations = packages.Select(x => Path.Combine(x.Descriptor.Location, x.Descriptor.Name));
|
||||
var packageViewEngines = _viewEngineProviders
|
||||
.Select(x => x.CreatePackagesViewEngine(new CreatePackagesViewEngineParams {VirtualPaths = packageLocations}));
|
||||
|
||||
viewResultBase.ViewEngineCollection = new ViewEngineCollection(
|
||||
themeViewEngines
|
||||
.Concat(packageViewEngines)
|
||||
.Concat(_viewEngines)
|
||||
.ToList());
|
||||
}
|
||||
|
||||
public void OnResultExecuted(ResultExecutedContext filterContext) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
19
src/Orchard/Mvc/ViewEngines/WebFormsViewEngineProvider.cs
Normal file
19
src/Orchard/Mvc/ViewEngines/WebFormsViewEngineProvider.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Orchard.Mvc.ViewEngines {
|
||||
public class WebFormsViewEngineProvider : IViewEngineProvider {
|
||||
public IViewEngine CreateThemeViewEngine(CreateThemeViewEngineParams parameters) {
|
||||
//var viewEngine = new WebFormViewEngine();
|
||||
//viewEngine.PartialViewLocationFormats
|
||||
return null;
|
||||
}
|
||||
|
||||
public IViewEngine CreatePackagesViewEngine(CreatePackagesViewEngineParams parameters) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -214,9 +214,12 @@
|
||||
<Compile Include="Mvc\Results\NotFoundResult.cs" />
|
||||
<Compile Include="Mvc\OrchardControllerIdentificationStrategy.cs" />
|
||||
<Compile Include="Mvc\Routes\RouteExtensions.cs" />
|
||||
<Compile Include="Mvc\ViewEngines\IViewEngineProvider.cs" />
|
||||
<Compile Include="Mvc\ViewEngines\LayoutView.cs" />
|
||||
<Compile Include="Mvc\ViewEngines\LayoutViewEngine.cs" />
|
||||
<Compile Include="Mvc\ViewEngines\OrchardLayoutContext.cs" />
|
||||
<Compile Include="Mvc\ViewEngines\ViewEngineFilter.cs" />
|
||||
<Compile Include="Mvc\ViewEngines\WebFormsViewEngineProvider.cs" />
|
||||
<Compile Include="Mvc\ViewModels\AdminViewModel.cs" />
|
||||
<Compile Include="Mvc\ViewModels\BaseViewModel.cs" />
|
||||
<Compile Include="Mvc\ViewPage.cs">
|
||||
@ -234,6 +237,7 @@
|
||||
<Compile Include="Tasks\IBackgroundTask.cs" />
|
||||
<Compile Include="Tasks\SweepGenerator.cs" />
|
||||
<Compile Include="Themes\ITheme.cs" />
|
||||
<Compile Include="Themes\IThemeSelector.cs" />
|
||||
<Compile Include="Themes\IThemeService.cs" />
|
||||
<Compile Include="Themes\ThemesModule.cs" />
|
||||
<Compile Include="UI\Menus\AdminMenuFilter.cs" />
|
||||
|
13
src/Orchard/Themes/IThemeSelector.cs
Normal file
13
src/Orchard/Themes/IThemeSelector.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Orchard.Themes {
|
||||
public class ThemeSelectorResult {
|
||||
public int Priority { get; set; }
|
||||
public string ThemeName { get; set; }
|
||||
}
|
||||
|
||||
public interface IThemeSelector : IDependency {
|
||||
ThemeSelectorResult GetTheme(RequestContext context);
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Orchard.Themes {
|
||||
public interface IThemeService : IDependency {
|
||||
ITheme GetCurrentTheme();
|
||||
ITheme GetThemeByName(string themeName);
|
||||
|
||||
ITheme GetSiteTheme();
|
||||
void SetSiteTheme(string themeName);
|
||||
ITheme GetRequestTheme(RequestContext requestContext);
|
||||
|
||||
IEnumerable<ITheme> GetInstalledThemes();
|
||||
void SetCurrentTheme(string themeName);
|
||||
void InstallTheme(HttpPostedFileBase file);
|
||||
void UninstallTheme(string themeName);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ namespace Orchard.Themes {
|
||||
if (themeProperty != null) {
|
||||
registration.Activated += (sender, e) => {
|
||||
var themeService = e.Context.Resolve<IThemeService>();
|
||||
var currentTheme = themeService.GetCurrentTheme();
|
||||
var currentTheme = themeService.GetSiteTheme();
|
||||
themeProperty.SetValue(e.Instance, currentTheme, null);
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user