diff --git a/src/Orchard.Core.Tests/Body/BodyPartTests.cs b/src/Orchard.Core.Tests/Body/BodyPartTests.cs index 4ada1e46f..c847407bb 100644 --- a/src/Orchard.Core.Tests/Body/BodyPartTests.cs +++ b/src/Orchard.Core.Tests/Body/BodyPartTests.cs @@ -17,8 +17,10 @@ using Orchard.DisplayManagement; using Orchard.DisplayManagement.Descriptors; using Orchard.DisplayManagement.Implementation; using Orchard.Environment; +using Orchard.Environment.Extensions; using Orchard.Security; using Orchard.Tests.Modules; +using Orchard.Tests.Stubs; using Orchard.UI.Notify; namespace Orchard.Core.Tests.Body { @@ -41,6 +43,7 @@ namespace Orchard.Core.Tests.Body { builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); } [Test] diff --git a/src/Orchard.Core.Tests/Common/Providers/CommonPartProviderTests.cs b/src/Orchard.Core.Tests/Common/Providers/CommonPartProviderTests.cs index abc4f4140..0451bdeef 100644 --- a/src/Orchard.Core.Tests/Common/Providers/CommonPartProviderTests.cs +++ b/src/Orchard.Core.Tests/Common/Providers/CommonPartProviderTests.cs @@ -20,12 +20,14 @@ using Orchard.Core.Scheduling.Services; using Orchard.DisplayManagement; using Orchard.DisplayManagement.Descriptors; using Orchard.DisplayManagement.Implementation; +using Orchard.Environment.Extensions; using Orchard.Localization; using Orchard.Security; using Orchard.Tasks.Scheduling; using Orchard.Tests.Modules; using Orchard.Core.Common.ViewModels; using System.Web.Mvc; +using Orchard.Tests.Stubs; namespace Orchard.Core.Tests.Common.Providers { [TestFixture] @@ -46,6 +48,7 @@ namespace Orchard.Core.Tests.Common.Providers { builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); _authn = new Mock(); _authz = new Mock(); diff --git a/src/Orchard.Core.Tests/Routable/Services/RoutableServiceTests.cs b/src/Orchard.Core.Tests/Routable/Services/RoutableServiceTests.cs index 9695ea068..848b89ab9 100644 --- a/src/Orchard.Core.Tests/Routable/Services/RoutableServiceTests.cs +++ b/src/Orchard.Core.Tests/Routable/Services/RoutableServiceTests.cs @@ -20,6 +20,7 @@ using Orchard.DisplayManagement; using Orchard.DisplayManagement.Descriptors; using Orchard.DisplayManagement.Implementation; using Orchard.Environment; +using Orchard.Environment.Extensions; using Orchard.Security; using Orchard.Tests.Modules; using System.Web.Mvc; @@ -56,6 +57,8 @@ namespace Orchard.Core.Tests.Routable.Services { builder.RegisterType().As(); builder.RegisterInstance(new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData()))).As(); builder.RegisterType().As(); + + builder.RegisterType().As(); } private IRoutableService _routableService; diff --git a/src/Orchard.Core.Tests/Scheduling/ScheduledTaskExecutorTests.cs b/src/Orchard.Core.Tests/Scheduling/ScheduledTaskExecutorTests.cs index 125266614..2966f1a19 100644 --- a/src/Orchard.Core.Tests/Scheduling/ScheduledTaskExecutorTests.cs +++ b/src/Orchard.Core.Tests/Scheduling/ScheduledTaskExecutorTests.cs @@ -12,9 +12,11 @@ using Orchard.Data; using Orchard.DisplayManagement; using Orchard.DisplayManagement.Descriptors; using Orchard.DisplayManagement.Implementation; +using Orchard.Environment.Extensions; using Orchard.Tasks; using Orchard.Tasks.Scheduling; using Orchard.Tests.Modules; +using Orchard.Tests.Stubs; namespace Orchard.Core.Tests.Scheduling { [TestFixture] @@ -40,6 +42,8 @@ namespace Orchard.Core.Tests.Scheduling { builder.RegisterType().As().Named("ScheduledTaskExecutor", typeof(IBackgroundTask)); builder.RegisterInstance(_handler).As(); + + builder.RegisterType().As(); } protected override IEnumerable DatabaseTypes { diff --git a/src/Orchard.Core.Tests/Scheduling/ScheduledTaskManagerTests.cs b/src/Orchard.Core.Tests/Scheduling/ScheduledTaskManagerTests.cs index 1c4cbd694..84b098ace 100644 --- a/src/Orchard.Core.Tests/Scheduling/ScheduledTaskManagerTests.cs +++ b/src/Orchard.Core.Tests/Scheduling/ScheduledTaskManagerTests.cs @@ -13,8 +13,10 @@ using Orchard.Data; using Orchard.DisplayManagement; using Orchard.DisplayManagement.Descriptors; using Orchard.DisplayManagement.Implementation; +using Orchard.Environment.Extensions; using Orchard.Tasks.Scheduling; using Orchard.Tests.Modules; +using Orchard.Tests.Stubs; namespace Orchard.Core.Tests.Scheduling { [TestFixture] @@ -43,6 +45,8 @@ namespace Orchard.Core.Tests.Scheduling { builder.RegisterInstance(new Mock().Object); builder.RegisterType().As(); + + builder.RegisterType().As(); } protected override IEnumerable DatabaseTypes { diff --git a/src/Orchard.Tests.Modules/Users/Controllers/AdminControllerTests.cs b/src/Orchard.Tests.Modules/Users/Controllers/AdminControllerTests.cs index e09778553..0f86ac51b 100644 --- a/src/Orchard.Tests.Modules/Users/Controllers/AdminControllerTests.cs +++ b/src/Orchard.Tests.Modules/Users/Controllers/AdminControllerTests.cs @@ -20,11 +20,13 @@ using Orchard.Environment; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; using Orchard.ContentManagement.Records; +using Orchard.Environment.Extensions; using Orchard.Localization; using Orchard.Messaging.Events; using Orchard.Messaging.Services; using Orchard.Security; using Orchard.Security.Permissions; +using Orchard.Tests.Stubs; using Orchard.UI.Notify; using Orchard.Users.Controllers; using Orchard.Users.Handlers; @@ -57,6 +59,7 @@ namespace Orchard.Tests.Modules.Users.Controllers { builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterInstance(new Mock().Object); _authorizer = new Mock(); builder.RegisterInstance(_authorizer.Object); diff --git a/src/Orchard.Tests.Modules/Users/Services/MembershipServiceTests.cs b/src/Orchard.Tests.Modules/Users/Services/MembershipServiceTests.cs index 1c8979fd5..3e00fcca5 100644 --- a/src/Orchard.Tests.Modules/Users/Services/MembershipServiceTests.cs +++ b/src/Orchard.Tests.Modules/Users/Services/MembershipServiceTests.cs @@ -17,9 +17,11 @@ using Orchard.ContentManagement.Records; using Orchard.DisplayManagement; using Orchard.DisplayManagement.Descriptors; using Orchard.DisplayManagement.Implementation; +using Orchard.Environment.Extensions; using Orchard.Messaging.Events; using Orchard.Messaging.Services; using Orchard.Security; +using Orchard.Tests.Stubs; using Orchard.Users.Handlers; using Orchard.Users.Models; using Orchard.Users.Services; @@ -80,6 +82,7 @@ namespace Orchard.Tests.Modules.Users.Services { builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); _session = _sessionFactory.OpenSession(); builder.RegisterInstance(new TestSessionLocator(_session)).As(); _container = builder.Build(); diff --git a/src/Orchard.Tests.Modules/Widgets/Services/WidgetsServiceTest.cs b/src/Orchard.Tests.Modules/Widgets/Services/WidgetsServiceTest.cs index f4e9a188f..58383840e 100644 --- a/src/Orchard.Tests.Modules/Widgets/Services/WidgetsServiceTest.cs +++ b/src/Orchard.Tests.Modules/Widgets/Services/WidgetsServiceTest.cs @@ -15,7 +15,9 @@ using Orchard.DisplayManagement; using Orchard.DisplayManagement.Descriptors; using Orchard.DisplayManagement.Implementation; using Orchard.Environment; +using Orchard.Environment.Extensions; using Orchard.Security; +using Orchard.Tests.Stubs; using Orchard.Themes; using Orchard.Themes.Models; using Orchard.UI.Notify; @@ -72,7 +74,7 @@ namespace Orchard.Tests.Modules.Widgets.Services { builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); - + builder.RegisterType().As(); Theme theme1 = new Theme { Zones = ThemeZoneName1 }; Theme theme2 = new Theme { Zones = ThemeZoneName2 }; Mock themeServiceMock = new Mock(); diff --git a/src/Orchard.Tests/ContentManagement/ContentQueryTests.cs b/src/Orchard.Tests/ContentManagement/ContentQueryTests.cs index a14a5f074..fd540c8ed 100644 --- a/src/Orchard.Tests/ContentManagement/ContentQueryTests.cs +++ b/src/Orchard.Tests/ContentManagement/ContentQueryTests.cs @@ -10,9 +10,11 @@ using Orchard.ContentManagement.Handlers; using Orchard.ContentManagement.Records; using Orchard.DisplayManagement; using Orchard.DisplayManagement.Descriptors; +using Orchard.Environment.Extensions; using Orchard.Tests.ContentManagement.Records; using Orchard.Tests.ContentManagement.Models; using Orchard.DisplayManagement.Implementation; +using Orchard.Tests.Stubs; namespace Orchard.Tests.ContentManagement { [TestFixture] @@ -64,6 +66,8 @@ namespace Orchard.Tests.ContentManagement { builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)); + builder.RegisterType().As(); + _session = _sessionFactory.OpenSession(); builder.RegisterInstance(new DefaultContentManagerTests.TestSessionLocator(_session)).As(); diff --git a/src/Orchard.Tests/ContentManagement/DefaultContentManagerTests.cs b/src/Orchard.Tests/ContentManagement/DefaultContentManagerTests.cs index 2cab092ed..c9524f9c2 100644 --- a/src/Orchard.Tests/ContentManagement/DefaultContentManagerTests.cs +++ b/src/Orchard.Tests/ContentManagement/DefaultContentManagerTests.cs @@ -12,12 +12,14 @@ using Orchard.Data; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; using Orchard.ContentManagement.Records; +using Orchard.Environment.Extensions; using Orchard.Tests.ContentManagement.Records; using Orchard.Tests.ContentManagement.Models; using Orchard.DisplayManagement.Descriptors; using Orchard.DisplayManagement.Implementation; using Orchard.DisplayManagement; using System.Collections.Generic; +using Orchard.Tests.Stubs; namespace Orchard.Tests.ContentManagement { [TestFixture] @@ -72,6 +74,8 @@ namespace Orchard.Tests.ContentManagement { builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); + builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)); _session = _sessionFactory.OpenSession(); diff --git a/src/Orchard.Tests/DisplayManagement/Descriptors/DefaultShapeTableManagerTests.cs b/src/Orchard.Tests/DisplayManagement/Descriptors/DefaultShapeTableManagerTests.cs index 00871a191..5c373dba5 100644 --- a/src/Orchard.Tests/DisplayManagement/Descriptors/DefaultShapeTableManagerTests.cs +++ b/src/Orchard.Tests/DisplayManagement/Descriptors/DefaultShapeTableManagerTests.cs @@ -1,9 +1,12 @@ using System; +using System.Collections.Generic; using System.Linq; +using System.Web; using Autofac; using NUnit.Framework; using Orchard.DisplayManagement.Descriptors; using Orchard.DisplayManagement.Implementation; +using Orchard.Environment.Extensions; using Orchard.Environment.Extensions.Models; namespace Orchard.Tests.DisplayManagement.Descriptors { @@ -12,12 +15,51 @@ namespace Orchard.Tests.DisplayManagement.Descriptors { protected override void Register(Autofac.ContainerBuilder builder) { builder.RegisterType().As(); + var features = new [] { + new FeatureDescriptor { + Name = "Theme1", + Extension = new ExtensionDescriptor { + Name = "Theme1", + ExtensionType = "Theme" + } + }, + new FeatureDescriptor { + Name = "DerivedTheme", + Extension = new ExtensionDescriptor { + Name = "DerivedTheme", + ExtensionType = "Theme", + BaseTheme = "BaseTheme" + } + }, + new FeatureDescriptor { + Name = "BaseTheme", + Extension = new ExtensionDescriptor { + Name = "BaseTheme", + ExtensionType = "Theme" + } + } + }; + builder.RegisterInstance(new TestExtensionManager(features)); + + TestShapeProvider.FeatureShapes = new Dictionary> { + { TestFeature(), new [] {"Hello"} }, + { Feature(features[0]), new [] {"Theme1Shape"} }, + { Feature(features[1]), new [] {"DerivedShape", "OverriddenShape"} }, + { Feature(features[2]), new [] {"BaseShape", "OverriddenShape"} } + }; + builder.RegisterType().As() - .WithMetadata("Feature", TestFeature()) + .WithMetadata("Features", TestFeature()) .As() .InstancePerLifetimeScope(); } + static Feature Feature(FeatureDescriptor descriptor) { + return new Feature { + Descriptor = descriptor + }; + } + static Feature TestFeature() { return new Feature { Descriptor = new FeatureDescriptor { @@ -31,12 +73,45 @@ namespace Orchard.Tests.DisplayManagement.Descriptors { }; } + public class TestExtensionManager : IExtensionManager { + private readonly IEnumerable _availableFeautures; + + public TestExtensionManager(IEnumerable availableFeautures) { + _availableFeautures = availableFeautures; + } + + public IEnumerable AvailableExtensions() { + throw new NotSupportedException(); + } + + public IEnumerable AvailableFeatures() { + return _availableFeautures; + } + + public IEnumerable LoadFeatures(IEnumerable featureDescriptors) { + throw new NotSupportedException(); + } + + public void InstallExtension(string extensionType, HttpPostedFileBase extensionBundle) { + throw new NotSupportedException(); + } + + public void UninstallExtension(string extensionType, string extensionName) { + throw new NotSupportedException(); + } + } + public class TestShapeProvider : IShapeTableProvider { + public static IDictionary> FeatureShapes; public Action Discover = x => { }; void IShapeTableProvider.Discover(ShapeTableBuilder builder) { - builder.Describe("Hello"); + foreach (var pair in FeatureShapes) { + foreach (var shape in pair.Value) { + builder.Describe(shape).From(pair.Key).BoundAs(pair.Key.Descriptor.Name, null); + } + } Discover(builder); } } @@ -64,7 +139,7 @@ namespace Orchard.Tests.DisplayManagement.Descriptors { Action cb4 = x => { }; _container.Resolve().Discover = - builder => builder.Describe("Foo") + builder => builder.Describe("Foo").From(TestFeature()) .OnCreating(cb1) .OnCreated(cb2) .OnDisplaying(cb3) @@ -79,5 +154,34 @@ namespace Orchard.Tests.DisplayManagement.Descriptors { Assert.That(foo.Displaying.Single(), Is.SameAs(cb3)); Assert.That(foo.Displayed.Single(), Is.SameAs(cb4)); } + + [Test] + public void OnlyShapesFromTheGivenThemeAreProvided() { + _container.Resolve(); + var manager = _container.Resolve(); + var table = manager.GetShapeTable("Theme1"); + Assert.IsTrue(table.Descriptors.ContainsKey("Theme1Shape")); + Assert.IsFalse(table.Descriptors.ContainsKey("DerivedShape")); + Assert.IsFalse(table.Descriptors.ContainsKey("BaseShape")); + } + + [Test] + public void ShapesFromTheBaseThemeAreProvided() { + _container.Resolve(); + var manager = _container.Resolve(); + var table = manager.GetShapeTable("DerivedTheme"); + Assert.IsFalse(table.Descriptors.ContainsKey("Theme1Shape")); + Assert.IsTrue(table.Descriptors.ContainsKey("DerivedShape")); + Assert.IsTrue(table.Descriptors.ContainsKey("BaseShape")); + } + + [Test] + public void DerivedThemesCanOverrideBaseThemeShapeBindings() { + _container.Resolve(); + var manager = _container.Resolve(); + var table = manager.GetShapeTable("DerivedTheme"); + Assert.IsTrue(table.Bindings.ContainsKey("OverriddenShape")); + Assert.AreEqual("DerivedTheme", table.Descriptors["OverriddenShape"].BindingSource); + } } } \ No newline at end of file diff --git a/src/Orchard.Tests/DisplayManagement/ShapeFactoryTests.cs b/src/Orchard.Tests/DisplayManagement/ShapeFactoryTests.cs index f612ab9a3..62a14a7f5 100644 --- a/src/Orchard.Tests/DisplayManagement/ShapeFactoryTests.cs +++ b/src/Orchard.Tests/DisplayManagement/ShapeFactoryTests.cs @@ -8,6 +8,8 @@ using Orchard.DisplayManagement; using Orchard.DisplayManagement.Descriptors; using Orchard.DisplayManagement.Implementation; using Orchard.DisplayManagement.Shapes; +using Orchard.Environment.Extensions; +using Orchard.Tests.Stubs; namespace Orchard.Tests.DisplayManagement { [TestFixture] @@ -20,6 +22,7 @@ namespace Orchard.Tests.DisplayManagement { builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); _container = builder.Build(); } diff --git a/src/Orchard.Tests/DisplayManagement/ShapeHelperTests.cs b/src/Orchard.Tests/DisplayManagement/ShapeHelperTests.cs index 2760037d1..2bfd69210 100644 --- a/src/Orchard.Tests/DisplayManagement/ShapeHelperTests.cs +++ b/src/Orchard.Tests/DisplayManagement/ShapeHelperTests.cs @@ -8,6 +8,8 @@ using Orchard.DisplayManagement; using Orchard.DisplayManagement.Descriptors; using Orchard.DisplayManagement.Implementation; using Orchard.DisplayManagement.Shapes; +using Orchard.Environment.Extensions; +using Orchard.Tests.Stubs; namespace Orchard.Tests.DisplayManagement { [TestFixture] @@ -20,6 +22,7 @@ namespace Orchard.Tests.DisplayManagement { builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); _container = builder.Build(); } diff --git a/src/Orchard.Tests/Orchard.Framework.Tests.csproj b/src/Orchard.Tests/Orchard.Framework.Tests.csproj index 635b194dd..801976249 100644 --- a/src/Orchard.Tests/Orchard.Framework.Tests.csproj +++ b/src/Orchard.Tests/Orchard.Framework.Tests.csproj @@ -244,6 +244,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.Themes/Services/ThemeService.cs b/src/Orchard.Web/Modules/Orchard.Themes/Services/ThemeService.cs index 0e0881748..829fbf860 100644 --- a/src/Orchard.Web/Modules/Orchard.Themes/Services/ThemeService.cs +++ b/src/Orchard.Web/Modules/Orchard.Themes/Services/ThemeService.cs @@ -119,7 +119,7 @@ namespace Orchard.Themes.Services { } while (themes.Count > 0) - _moduleService.DisableFeatures(new[] {themes.Pop()}); + _moduleService.EnableFeatures(new[] {themes.Pop()}); } public ITheme GetRequestTheme(RequestContext requestContext) { diff --git a/src/Orchard/DisplayManagement/Descriptors/DefaultShapeTableManager.cs b/src/Orchard/DisplayManagement/Descriptors/DefaultShapeTableManager.cs index 3e1738ab9..c2f68fc30 100644 --- a/src/Orchard/DisplayManagement/Descriptors/DefaultShapeTableManager.cs +++ b/src/Orchard/DisplayManagement/Descriptors/DefaultShapeTableManager.cs @@ -3,7 +3,9 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using Autofac.Features.Metadata; +using Orchard.Environment.Extensions; using Orchard.Environment.Extensions.Models; +using Orchard.Utility; namespace Orchard.DisplayManagement.Descriptors { @@ -13,8 +15,12 @@ namespace Orchard.DisplayManagement.Descriptors { public class DefaultShapeTableManager : IShapeTableManager { private readonly IEnumerable> _bindingStrategies; + private readonly IExtensionManager _extensionManager; - public DefaultShapeTableManager(IEnumerable> bindingStrategies) { + public DefaultShapeTableManager( + IEnumerable> bindingStrategies, + IExtensionManager extensionManager) { + _extensionManager = extensionManager; _bindingStrategies = bindingStrategies; } @@ -30,7 +36,8 @@ namespace Orchard.DisplayManagement.Descriptors { } var alterations = builderFactory.BuildAlterations() - .Where(alteration => IsModuleOrRequestedTheme(alteration, themeName)); + .Where(alteration => IsModuleOrRequestedTheme(alteration, themeName)) + .OrderByDependencies(AlterationHasDependency); var descriptors = alterations.GroupBy(alteration => alteration.ShapeType, StringComparer.OrdinalIgnoreCase) .Select(group => group.Aggregate( @@ -47,8 +54,11 @@ namespace Orchard.DisplayManagement.Descriptors { }); } + private static bool AlterationHasDependency(ShapeAlteration item, ShapeAlteration subject) { + return ExtensionManager.HasDependency(item.Feature.Descriptor, subject.Feature.Descriptor); + } - static bool IsModuleOrRequestedTheme(ShapeAlteration alteration, string themeName) { + private bool IsModuleOrRequestedTheme(ShapeAlteration alteration, string themeName) { if (alteration == null || alteration.Feature == null || alteration.Feature.Descriptor == null || @@ -57,10 +67,36 @@ namespace Orchard.DisplayManagement.Descriptors { } var extensionType = alteration.Feature.Descriptor.Extension.ExtensionType; - var featureName = alteration.Feature.Descriptor.Name; - return extensionType == "Module" || - (extensionType == "Theme" && featureName == themeName); + if (extensionType == "Module") { + return true; + } + + if (extensionType == "Theme") { + // alterations from themes must be from the given theme or a base theme + var featureName = alteration.Feature.Descriptor.Name; + return featureName == themeName || IsBaseTheme(featureName, themeName); + } + + return false; + } + + private bool IsBaseTheme(string featureName, string themeName) { + // determine if the given feature is a base theme of the given theme + var availableFeatures = _extensionManager.AvailableFeatures(); + + var themeFeature = availableFeatures.SingleOrDefault(fd => fd.Name == themeName); + while(themeFeature != null) { + var baseTheme = themeFeature.Extension.BaseTheme; + if (String.IsNullOrEmpty(baseTheme)) { + return false; + } + if (featureName == baseTheme) { + return true; + } + themeFeature = availableFeatures.SingleOrDefault(fd => fd.Name == baseTheme); + } + return false; } class ShapeTableBuilderFactory { diff --git a/src/Orchard/DisplayManagement/Descriptors/ShapeTemplateStrategy/ShapeTemplateBindingStrategy.cs b/src/Orchard/DisplayManagement/Descriptors/ShapeTemplateStrategy/ShapeTemplateBindingStrategy.cs index 03a093693..5e3f708fe 100644 --- a/src/Orchard/DisplayManagement/Descriptors/ShapeTemplateStrategy/ShapeTemplateBindingStrategy.cs +++ b/src/Orchard/DisplayManagement/Descriptors/ShapeTemplateStrategy/ShapeTemplateBindingStrategy.cs @@ -38,7 +38,7 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy { var harvesterInfos = _harvesters.Select(harvester => new { harvester, subPaths = harvester.SubPaths() }); var availableFeatures = _extensionManager.AvailableFeatures(); - var activeFeatures = availableFeatures.Where(fd => FeatureIsTheme(fd) || FeatureIsEnabled(fd)); + var activeFeatures = availableFeatures.Where(FeatureIsEnabled); var activeExtensions = Once(activeFeatures); var hits = activeExtensions.SelectMany(extensionDescriptor => { @@ -81,12 +81,9 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy { } } - private bool FeatureIsTheme(FeatureDescriptor fd) { - return fd.Extension.ExtensionType == "Theme"; - } - private bool FeatureIsEnabled(FeatureDescriptor fd) { - return _shellDescriptor.Features.Any(sf => sf.Name == fd.Name); + return (fd.Extension.ExtensionType == "Theme" && fd.Name == "TheAdmin") || + _shellDescriptor.Features.Any(sf => sf.Name == fd.Name); } private IHtmlString Render(ShapeDescriptor shapeDescriptor, DisplayContext displayContext, HarvestShapeInfo harvestShapeInfo, HarvestShapeHit harvestShapeHit) { diff --git a/src/Orchard/Environment/Extensions/ExtensionManager.cs b/src/Orchard/Environment/Extensions/ExtensionManager.cs index 733f27ace..12b2baf9b 100644 --- a/src/Orchard/Environment/Extensions/ExtensionManager.cs +++ b/src/Orchard/Environment/Extensions/ExtensionManager.cs @@ -48,17 +48,23 @@ namespace Orchard.Environment.Extensions { /// /// /// - static bool HasDependency(FeatureDescriptor item, FeatureDescriptor subject) { - // Themes implicitly depend on modules to ensure build and override ordering - if (item.Extension.ExtensionType == "Theme" && subject.Extension.ExtensionType == "Module") - return true; + internal static bool HasDependency(FeatureDescriptor item, FeatureDescriptor subject) { + if (item.Extension.ExtensionType == "Theme") { + // Themes implicitly depend on modules to ensure build and override ordering + if (subject.Extension.ExtensionType == "Module") { + return true; + } + if (subject.Extension.ExtensionType == "Theme") { + // theme depends on another if it is its base theme + return item.Extension.BaseTheme == subject.Name; + } + } // Return based on explicit dependencies return item.Dependencies != null && item.Dependencies.Any(x => StringComparer.OrdinalIgnoreCase.Equals(x, subject.Name)); } - private IEnumerable LoadedExtensions() { foreach ( var descriptor in AvailableExtensions() ) { ExtensionEntry entry = null;