mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-14 10:54:50 +08:00
Merge
--HG-- branch : dev
This commit is contained in:
@@ -21,9 +21,9 @@ namespace Orchard.Specs.Bindings {
|
||||
webApp.GivenIHaveACleanSiteWith(
|
||||
virtualDirectory,
|
||||
TableData(
|
||||
new { extension = DefaultExtensionTypes.Module, names = "Orchard.Setup, Orchard.Pages, Orchard.Blogs, Orchard.Messaging, Orchard.Modules, Orchard.Packaging, Orchard.PublishLater, Orchard.Themes, Orchard.Scripting, Orchard.Widgets, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.jQuery, Orchard.Tags, TinyMce" },
|
||||
new { extension = DefaultExtensionTypes.Core, names = "Common, Dashboard, Feeds, HomePage, Navigation, Contents, Routable, Scheduling, Settings, Shapes, XmlRpc" },
|
||||
new { extension = DefaultExtensionTypes.Theme, names = "SafeMode, TheAdmin, TheThemeMachine" }));
|
||||
new { extension = "Module", names = "Orchard.Setup, Orchard.Pages, Orchard.Blogs, Orchard.Messaging, Orchard.Modules, Orchard.Packaging, Orchard.PublishLater, Orchard.Themes, Orchard.Scripting, Orchard.Widgets, Orchard.Users, Orchard.Roles, Orchard.Comments, Orchard.jQuery, Orchard.Tags, TinyMce" },
|
||||
new { extension = "Core", names = "Common, Dashboard, Feeds, HomePage, Navigation, Contents, Routable, Scheduling, Settings, Shapes, XmlRpc" },
|
||||
new { extension = "Theme", names = "SafeMode, TheAdmin, TheThemeMachine" }));
|
||||
|
||||
webApp.WhenIGoTo("Setup");
|
||||
|
||||
|
@@ -140,13 +140,13 @@ namespace Orchard.Specs.Bindings {
|
||||
foreach (var row in table.Rows) {
|
||||
foreach (var name in row["names"].Split(',').Select(x => x.Trim())) {
|
||||
switch (row["extension"]) {
|
||||
case DefaultExtensionTypes.Core:
|
||||
case "Core":
|
||||
GivenIHaveCore(name);
|
||||
break;
|
||||
case DefaultExtensionTypes.Module:
|
||||
case "Module":
|
||||
GivenIHaveModule(name);
|
||||
break;
|
||||
case DefaultExtensionTypes.Theme:
|
||||
case "Theme":
|
||||
GivenIHaveTheme(name);
|
||||
break;
|
||||
default:
|
||||
|
@@ -25,7 +25,7 @@
|
||||
}
|
||||
|
||||
//temporarily "disable" actions on core features
|
||||
var showActions = categoryName.ToString() != "Core";
|
||||
bool showActions;
|
||||
<li class="@categoryClassName">
|
||||
<h2>@categoryName</h2>
|
||||
<ul>@{
|
||||
@@ -46,9 +46,7 @@
|
||||
select (from f in Model.Features where f.Descriptor.Id == d select f).SingleOrDefault()).Where(f => f != null).OrderBy(f => f.Descriptor.Name);
|
||||
var missingDependencies = feature.Descriptor.Dependencies
|
||||
.Where(d => !Model.Features.Any(f => f.Descriptor.Id == d));
|
||||
if (showActions) {
|
||||
showActions = missingDependencies.Count() == 0;
|
||||
}
|
||||
showActions = categoryName.ToString() != "Core" && missingDependencies.Count() == 0;
|
||||
<li class="@featureClassName" id="@featureId" title="@T("{0} is {1}", Html.AttributeEncode(featureName), featureState)">
|
||||
<div class="summary">
|
||||
<div class="properties">
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false" />
|
||||
</configSections>
|
||||
|
||||
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
<add key="log4net.Config" value="Config\log4net.config" />
|
||||
@@ -143,7 +143,8 @@
|
||||
<probing privatePath="App_Data/Dependencies"/>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="2.0.0.0" newVersion="3.0.0.0" />
|
||||
<bindingRedirect oldVersion="1.0.0.0" newVersion="3.0.0.0"/>
|
||||
<bindingRedirect oldVersion="2.0.0.0" newVersion="3.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
@@ -15,13 +15,7 @@ namespace Orchard.Environment.Extensions {
|
||||
|
||||
public static class ExtensionManagerExtensions {
|
||||
public static IEnumerable<FeatureDescriptor> EnabledFeatures(this IExtensionManager extensionManager, ShellDescriptor descriptor) {
|
||||
return extensionManager.AvailableExtensions()
|
||||
.SelectMany(extensionDescriptor => extensionDescriptor.Features)
|
||||
.Where(featureDescriptor => IsFeatureEnabledInDescriptor(featureDescriptor, descriptor));
|
||||
}
|
||||
|
||||
private static bool IsFeatureEnabledInDescriptor(FeatureDescriptor featureDescriptor, ShellDescriptor shellDescriptor) {
|
||||
return shellDescriptor.Features.Any(shellDescriptorFeature => shellDescriptorFeature.Name == featureDescriptor.Id);
|
||||
return extensionManager.AvailableFeatures().Where(fd => descriptor.Features.Any(sf => sf.Name == fd.Id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@ namespace Orchard.Environment.Extensions.Models {
|
||||
public static class DefaultExtensionTypes {
|
||||
public const string Module = "Module";
|
||||
public const string Theme = "Theme";
|
||||
public const string Core = "Core";
|
||||
|
||||
public static bool IsModule(string extensionType) {
|
||||
return string.Equals(extensionType, Module, StringComparison.OrdinalIgnoreCase);
|
||||
|
@@ -5,6 +5,7 @@ using System.Web.Mvc;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.Logging;
|
||||
|
||||
namespace Orchard.Mvc.ViewEngines.ThemeAwareness {
|
||||
public interface IThemeAwareViewEngine : IDependency {
|
||||
@@ -31,8 +32,12 @@ namespace Orchard.Mvc.ViewEngines.ThemeAwareness {
|
||||
_configuredEnginesCache = configuredEnginesCache;
|
||||
_extensionManager = extensionManager;
|
||||
_shellDescriptor = shellDescriptor;
|
||||
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache, bool useDeepPaths) {
|
||||
var engines = _nullEngines;
|
||||
|
||||
@@ -71,21 +76,82 @@ namespace Orchard.Mvc.ViewEngines.ThemeAwareness {
|
||||
|
||||
private IViewEngine DeepEngines(ExtensionDescriptor theme) {
|
||||
return _configuredEnginesCache.BindDeepEngines(theme.Id, () => {
|
||||
// The order for searching for views is:
|
||||
// 1. Current "theme"
|
||||
// 2. Base themes of the current theme (in "base" order)
|
||||
// 3. Active features from modules in dependency order
|
||||
|
||||
var engines = Enumerable.Empty<IViewEngine>();
|
||||
var themeLocation = theme.Location + "/" + theme.Id;
|
||||
// 1. current theme
|
||||
engines = engines.Concat(CreateThemeViewEngines(theme));
|
||||
|
||||
var themeParams = new CreateThemeViewEngineParams { VirtualPath = themeLocation };
|
||||
engines = engines.Concat(_viewEngineProviders.Select(vep => vep.CreateThemeViewEngine(themeParams)));
|
||||
// 2. Base themes of the current theme (in "base" order)
|
||||
engines = GetBaseThemes(theme).Aggregate(engines, (current, baseTheme) => current.Concat(CreateThemeViewEngines(baseTheme)));
|
||||
|
||||
var activeFeatures = _extensionManager.AvailableFeatures().Where(fd => _shellDescriptor.Features.Any(sdf => sdf.Name == fd.Id));
|
||||
var activeModuleLocations = activeFeatures.Select(fd => fd.Extension.Location + "/" + fd.Extension.Id).Distinct();
|
||||
var moduleParams = new CreateModulesViewEngineParams { VirtualPaths = activeModuleLocations };
|
||||
// 3. Active features from modules in dependency order
|
||||
var enabledModules = _extensionManager.EnabledFeatures(_shellDescriptor)
|
||||
.Reverse() // reverse from (C <= B <= A) to (A => B => C)
|
||||
.Where(fd => DefaultExtensionTypes.IsModule(fd.Extension.ExtensionType));
|
||||
|
||||
var allLocations = enabledModules.Concat(enabledModules)
|
||||
.Select(fd => fd.Extension.Location + "/" + fd.Extension.Id)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
|
||||
var moduleParams = new CreateModulesViewEngineParams { VirtualPaths = allLocations };
|
||||
engines = engines.Concat(_viewEngineProviders.Select(vep => vep.CreateModulesViewEngine(moduleParams)));
|
||||
|
||||
return new ViewEngineCollectionWrapper(engines);
|
||||
});
|
||||
}
|
||||
|
||||
private IEnumerable<IViewEngine> CreateThemeViewEngines(ExtensionDescriptor theme) {
|
||||
var themeLocation = theme.Location + "/" + theme.Id;
|
||||
var themeParams = new CreateThemeViewEngineParams {VirtualPath = themeLocation};
|
||||
return _viewEngineProviders.Select(vep => vep.CreateThemeViewEngine(themeParams));
|
||||
}
|
||||
|
||||
private IEnumerable<ExtensionDescriptor> GetBaseThemes(ExtensionDescriptor themeExtension) {
|
||||
if (themeExtension.Id.Equals("TheAdmin", StringComparison.OrdinalIgnoreCase)) {
|
||||
// Special case: conceptually, the base themes of "TheAdmin" is the list of all
|
||||
// enabled themes. This is so that any enabled theme can have controller/action/views
|
||||
// in the Admin of the site.
|
||||
return _extensionManager
|
||||
.EnabledFeatures(_shellDescriptor)
|
||||
.Reverse() // reverse from (C <= B <= A) to (A => B => C)
|
||||
.Select(fd => fd.Extension)
|
||||
.Where(fd => DefaultExtensionTypes.IsTheme(fd.ExtensionType));
|
||||
}
|
||||
else {
|
||||
var availableFeatures = _extensionManager.AvailableFeatures();
|
||||
var list = new List<ExtensionDescriptor>();
|
||||
while(true) {
|
||||
if (themeExtension == null)
|
||||
break;
|
||||
|
||||
if (String.IsNullOrEmpty(themeExtension.BaseTheme))
|
||||
break;
|
||||
|
||||
var baseFeature = availableFeatures.FirstOrDefault(fd => fd.Id == themeExtension.BaseTheme);
|
||||
if (baseFeature == null) {
|
||||
Logger.Error("Base theme '{0}' of theme '{1}' not found in list of features", themeExtension.BaseTheme, themeExtension.Id);
|
||||
break;
|
||||
}
|
||||
|
||||
// Protect against potential infinite loop
|
||||
if (list.Contains(baseFeature.Extension)) {
|
||||
Logger.Error("Base theme '{0}' of theme '{1}' ignored, as it seems there is recursion in base themes", themeExtension.BaseTheme, themeExtension.Id);
|
||||
break;
|
||||
}
|
||||
|
||||
list.Add(baseFeature.Extension);
|
||||
|
||||
themeExtension = baseFeature.Extension;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public void ReleaseView(ControllerContext controllerContext, IView view) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
Reference in New Issue
Block a user