--HG--
branch : dev
This commit is contained in:
Suha Can
2010-12-08 18:58:32 -08:00
7 changed files with 84 additions and 26 deletions

View File

@@ -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");

View File

@@ -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:

View File

@@ -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">

View File

@@ -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>

View File

@@ -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));
}
}
}

View File

@@ -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);

View File

@@ -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();
}