mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-14 19:04:51 +08:00
Additional Module and Theme directories (squashed commit)
This commit is contained in:
@@ -6,6 +6,7 @@ using Moq;
|
||||
using NUnit.Framework;
|
||||
using Orchard.Caching;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Extensions.Compilers;
|
||||
using Orchard.Environment.Extensions.Loaders;
|
||||
using Orchard.FileSystems.AppData;
|
||||
@@ -151,8 +152,9 @@ namespace Orchard.Tests.Environment.Loaders {
|
||||
IHostEnvironment hostEnvironment,
|
||||
IAssemblyProbingFolder assemblyProbingFolder,
|
||||
IDependenciesFolder dependenciesFolder,
|
||||
IProjectFileParser projectFileParser)
|
||||
: base(buildManager, virtualPathProvider, virtualPathMonitor, hostEnvironment, assemblyProbingFolder, dependenciesFolder, projectFileParser) {}
|
||||
IProjectFileParser projectFileParser,
|
||||
ExtensionLocations extensionLocations)
|
||||
: base(buildManager, virtualPathProvider, virtualPathMonitor, hostEnvironment, assemblyProbingFolder, dependenciesFolder, projectFileParser, extensionLocations) {}
|
||||
|
||||
public IEnumerable<string> GetDependenciesAccessor(string projectPath) {
|
||||
return GetDependencies(projectPath);
|
||||
|
@@ -15,6 +15,14 @@
|
||||
<add key="webpages:Version" value="3.0.3"/>
|
||||
<add key="log4net.Config" value="Config\log4net.config"/>
|
||||
<add key="owin:AppStartup" value="Orchard.Owin.Startup, Orchard.Framework"/>
|
||||
|
||||
<!-- Optional additional comma-separated list of folders for Modules or Themes -->
|
||||
<!-- Note: Themes that are not under ~/Themes/ should have web.config with appropriate access permissions. -->
|
||||
|
||||
<!--
|
||||
<add key="Modules" value="~/Ibn_Modules,~/Customer1/Modules"/>
|
||||
<add key="Themes" value="~/Themes/MoreThemes,~/Customer1/Themes" />
|
||||
-->
|
||||
</appSettings>
|
||||
|
||||
<system.web.webPages.razor>
|
||||
|
107
src/Orchard/Environment/Configuration/ExtensionLocations.cs
Normal file
107
src/Orchard/Environment/Configuration/ExtensionLocations.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
|
||||
namespace Orchard.Environment.Configuration {
|
||||
public class ExtensionLocations : IDependency {
|
||||
public string[] CoreLocations;
|
||||
public string[] ModuleLocations;
|
||||
public string[] ThemeLocations;
|
||||
public string[] CommonLocations; // locations that should not be common and not related to the current tenant
|
||||
public string[] ModuleAndThemeLocations;
|
||||
public string[] ExtensionsVirtualPathPrefixes; // Modules+Themes (no core)
|
||||
|
||||
public ExtensionLocations() {
|
||||
Init(new DefaultAppConfigurationAccessor());
|
||||
}
|
||||
|
||||
// This optional constructor can be used to create an environment that takes AppConfigurations from IAppConfigurationAccessor instead of from the global ConfigurationManager.AppSettings
|
||||
public ExtensionLocations(IAppConfigurationAccessor appConfigurationAccessor) {
|
||||
Init(appConfigurationAccessor);
|
||||
}
|
||||
|
||||
public virtual void Init(IAppConfigurationAccessor appConfigurationAccessor) {
|
||||
CoreLocations = new string[] {"~/Core"};
|
||||
ModuleLocations = GetConfigPaths(appConfigurationAccessor, "Modules", "~/Modules");
|
||||
ThemeLocations = GetConfigPaths(appConfigurationAccessor, "Themes", "~/Themes" );
|
||||
CommonLocations = GetConfigPaths(appConfigurationAccessor, "Common", "~/Media")
|
||||
.Concat(ThemeLocations)
|
||||
.Concat(ModuleLocations)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToArray();
|
||||
ModuleAndThemeLocations = ModuleLocations
|
||||
.Concat(ThemeLocations)
|
||||
.Distinct(StringComparer.CurrentCultureIgnoreCase)
|
||||
.ToArray();
|
||||
ExtensionsVirtualPathPrefixes = ModuleAndThemeLocations
|
||||
.Select(l=>l+"/")
|
||||
.OrderBy(l=>l.Count(c=>c=='/'))
|
||||
.Reverse()
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return module from path that is constructed as Location/Module/relative/path/in/module
|
||||
/// Path prefixes is expected as list of Location/ (location+trailing "/")
|
||||
///
|
||||
/// Extension locations can contain '/' so they are matched with deeper path first
|
||||
/// </summary>
|
||||
/// <param name="virtualPath"></param>
|
||||
/// <returns>the module - or null of not found</returns>
|
||||
public static string ModuleMatch(string virtualPath, IEnumerable<string> pathPrefixes) {
|
||||
foreach(string prefix in pathPrefixes) {
|
||||
if(virtualPath.StartsWith(prefix)) {
|
||||
int index = virtualPath.IndexOf('/', prefix.Length, virtualPath.Length - prefix.Length);
|
||||
if (index <= 0)
|
||||
continue;
|
||||
var moduleName = virtualPath.Substring(prefix.Length, index - prefix.Length);
|
||||
return (string.IsNullOrEmpty(moduleName) ? null : moduleName);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return module from path that is constructed as ExtensionLocation/Module/relative/path/in/module
|
||||
///
|
||||
/// Extension locations can contain '/' so they are matched with deeper path first
|
||||
/// </summary>
|
||||
/// <param name="virtualPath"></param>
|
||||
/// <returns>the module - or null of not found</returns>
|
||||
public string ExtensionsModuleMatch(string virtualPath) {
|
||||
ModuleMatch(virtualPath, ExtensionsVirtualPathPrefixes);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return true if the virtual path starts with any of the prefixes
|
||||
/// </summary>
|
||||
public static bool PrefixMatch(string virtualPath, IEnumerable<string> pathPrefixes) {
|
||||
return pathPrefixes.Any(p => virtualPath.StartsWith(p));
|
||||
}
|
||||
|
||||
public bool ExtensionsPrefixMatch(string virtualPath) {
|
||||
return PrefixMatch(virtualPath, ExtensionsVirtualPathPrefixes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get list of comma separated paths from web.config appSettings
|
||||
/// Also return the default path
|
||||
/// </summary>
|
||||
static string[] GetConfigPaths(IAppConfigurationAccessor appConfigurationAccessor, string key, string defaultPath) {
|
||||
char[] delim = { ',' };
|
||||
string configuration = appConfigurationAccessor.GetConfiguration(key) ?? "";
|
||||
return configuration.Split(delim, StringSplitOptions.RemoveEmptyEntries).Concat(new string[] { defaultPath }).Select(s => s.Trim()).Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
|
||||
}
|
||||
|
||||
private class DefaultAppConfigurationAccessor : IAppConfigurationAccessor {
|
||||
public DefaultAppConfigurationAccessor() {}
|
||||
|
||||
public string GetConfiguration(string name) {
|
||||
return ConfigurationManager.AppSettings[name];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -41,12 +41,14 @@ namespace Orchard.Environment.Extensions {
|
||||
}
|
||||
|
||||
public void MonitorExtensionsWork(Action<IVolatileToken> monitor) {
|
||||
var locations = _extensionManager.AvailableExtensions().Select(e => e.Location).Distinct(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
Logger.Information("Start monitoring extension files...");
|
||||
// Monitor add/remove of any module/theme
|
||||
Logger.Debug("Monitoring virtual path \"{0}\"", "~/Modules");
|
||||
monitor(_virtualPathMonitor.WhenPathChanges("~/Modules"));
|
||||
Logger.Debug("Monitoring virtual path \"{0}\"", "~/Themes");
|
||||
monitor(_virtualPathMonitor.WhenPathChanges("~/Themes"));
|
||||
foreach(string location in locations) {
|
||||
Logger.Debug("Monitoring virtual path \"{0}\"", location);
|
||||
monitor(_virtualPathMonitor.WhenPathChanges(location));
|
||||
}
|
||||
|
||||
// Give loaders a chance to monitor any additional changes
|
||||
var extensions = _extensionManager.AvailableExtensions().Where(d => DefaultExtensionTypes.IsModule(d.ExtensionType) || DefaultExtensionTypes.IsTheme(d.ExtensionType)).ToList();
|
||||
|
@@ -4,6 +4,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Orchard.Caching;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Extensions.Compilers;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
using Orchard.FileSystems.Dependencies;
|
||||
@@ -13,7 +14,7 @@ using Orchard.Utility.Extensions;
|
||||
|
||||
namespace Orchard.Environment.Extensions.Loaders {
|
||||
public class DynamicExtensionLoader : ExtensionLoaderBase {
|
||||
public static readonly string[] ExtensionsVirtualPathPrefixes = { "~/Modules/", "~/Themes/" };
|
||||
private readonly string[] _extensionsVirtualPathPrefixes; // { "~/Modules/", "~/Themes/" };
|
||||
|
||||
private readonly IBuildManager _buildManager;
|
||||
private readonly IVirtualPathProvider _virtualPathProvider;
|
||||
@@ -31,7 +32,8 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
IHostEnvironment hostEnvironment,
|
||||
IAssemblyProbingFolder assemblyProbingFolder,
|
||||
IDependenciesFolder dependenciesFolder,
|
||||
IProjectFileParser projectFileParser)
|
||||
IProjectFileParser projectFileParser,
|
||||
ExtensionLocations extensionLocations)
|
||||
: base(dependenciesFolder) {
|
||||
|
||||
_buildManager = buildManager;
|
||||
@@ -43,6 +45,8 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
_dependenciesFolder = dependenciesFolder;
|
||||
|
||||
Logger = NullLogger.Instance;
|
||||
|
||||
_extensionsVirtualPathPrefixes = extensionLocations.ModuleAndThemeLocations;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
@@ -209,8 +213,8 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
}
|
||||
|
||||
private void AddDependencies(string projectPath, HashSet<string> currentSet) {
|
||||
// Skip files from locations other than "~/Modules" and "~/Themes"
|
||||
if (string.IsNullOrEmpty(PrefixMatch(projectPath, ExtensionsVirtualPathPrefixes))) {
|
||||
// Skip files from locations other than "~/Modules" and "~/Themes" etc.
|
||||
if (string.IsNullOrEmpty(PrefixMatch(projectPath, _extensionsVirtualPathPrefixes))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -25,7 +25,8 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
if (Disabled)
|
||||
return null;
|
||||
|
||||
if (descriptor.Location == "~/Themes") {
|
||||
// Temporary - theme without own project should be under ~/themes
|
||||
if (descriptor.Location.StartsWith("~/Themes",StringComparison.InvariantCultureIgnoreCase)) {
|
||||
string projectPath = _virtualPathProvider.Combine(descriptor.Location, descriptor.Id,
|
||||
descriptor.Id + ".csproj");
|
||||
|
||||
@@ -44,7 +45,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
return new ExtensionProbeEntry {
|
||||
Descriptor = descriptor,
|
||||
Loader = this,
|
||||
VirtualPath = "~/Theme/" + descriptor.Id,
|
||||
VirtualPath = descriptor.VirtualPath,
|
||||
VirtualPathDependencies = Enumerable.Empty<string>(),
|
||||
};
|
||||
}
|
||||
|
@@ -12,6 +12,8 @@ namespace Orchard.Environment.Extensions.Models {
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
public string VirtualPath { get { return Location + "/" + Id; } }
|
||||
|
||||
/// <summary>
|
||||
/// The extension type.
|
||||
/// </summary>
|
||||
|
@@ -35,11 +35,18 @@ using Orchard.Mvc.ViewEngines.ThemeAwareness;
|
||||
using Orchard.Services;
|
||||
using Orchard.WebApi;
|
||||
using Orchard.WebApi.Filters;
|
||||
using System.Linq;
|
||||
using System.Web.Configuration;
|
||||
|
||||
namespace Orchard.Environment {
|
||||
public static class OrchardStarter {
|
||||
public static IContainer CreateHostContainer(Action<ContainerBuilder> registrations) {
|
||||
ExtensionLocations extensionLocations = new ExtensionLocations();
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
// Application paths and parameters
|
||||
builder.RegisterInstance(extensionLocations);
|
||||
|
||||
builder.RegisterModule(new CollectionOrderModule());
|
||||
builder.RegisterModule(new LoggingModule());
|
||||
builder.RegisterModule(new EventsModule());
|
||||
@@ -79,7 +86,6 @@ namespace Orchard.Environment {
|
||||
RegisterVolatileProvider<DefaultVirtualPathMonitor, IVirtualPathMonitor>(builder);
|
||||
RegisterVolatileProvider<DefaultVirtualPathProvider, IVirtualPathProvider>(builder);
|
||||
|
||||
|
||||
builder.RegisterType<DefaultOrchardHost>().As<IOrchardHost>().As<IEventHandler>()
|
||||
.Named<IEventHandler>(typeof(IShellSettingsManagerEventHandler).Name)
|
||||
.Named<IEventHandler>(typeof(IShellDescriptorManagerEventHandler).Name)
|
||||
@@ -100,11 +106,11 @@ namespace Orchard.Environment {
|
||||
{
|
||||
builder.RegisterType<ExtensionHarvester>().As<IExtensionHarvester>().SingleInstance();
|
||||
builder.RegisterType<ModuleFolders>().As<IExtensionFolders>().SingleInstance()
|
||||
.WithParameter(new NamedParameter("paths", new[] { "~/Modules" }));
|
||||
.WithParameter(new NamedParameter("paths", extensionLocations.ModuleLocations));
|
||||
builder.RegisterType<CoreModuleFolders>().As<IExtensionFolders>().SingleInstance()
|
||||
.WithParameter(new NamedParameter("paths", new[] { "~/Core" }));
|
||||
.WithParameter(new NamedParameter("paths", extensionLocations.CoreLocations));
|
||||
builder.RegisterType<ThemeFolders>().As<IExtensionFolders>().SingleInstance()
|
||||
.WithParameter(new NamedParameter("paths", new[] { "~/Themes" }));
|
||||
.WithParameter(new NamedParameter("paths", extensionLocations.ThemeLocations));
|
||||
|
||||
builder.RegisterType<CoreExtensionLoader>().As<IExtensionLoader>().SingleInstance();
|
||||
builder.RegisterType<ReferencedExtensionLoader>().As<IExtensionLoader>().SingleInstance();
|
||||
@@ -174,7 +180,6 @@ namespace Orchard.Environment {
|
||||
return container;
|
||||
}
|
||||
|
||||
|
||||
private static void RegisterVolatileProvider<TRegister, TService>(ContainerBuilder builder) where TService : IVolatileProvider {
|
||||
builder.RegisterType<TRegister>()
|
||||
.As<TService>()
|
||||
|
@@ -4,6 +4,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Folders;
|
||||
using Orchard.Environment.Extensions.Loaders;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.Logging;
|
||||
@@ -15,10 +19,14 @@ namespace Orchard.FileSystems.Dependencies {
|
||||
/// </summary>
|
||||
public class DynamicModuleVirtualPathProvider : VirtualPathProvider, ICustomVirtualPathProvider {
|
||||
private readonly IExtensionDependenciesManager _extensionDependenciesManager;
|
||||
private string[] _extensionsVirtualPathPrefixes;
|
||||
|
||||
public DynamicModuleVirtualPathProvider(IExtensionDependenciesManager extensionDependenciesManager) {
|
||||
|
||||
public DynamicModuleVirtualPathProvider(IExtensionDependenciesManager extensionDependenciesManager, ExtensionLocations extensionLocations) {
|
||||
_extensionDependenciesManager = extensionDependenciesManager;
|
||||
Logger = NullLogger.Instance;
|
||||
|
||||
_extensionsVirtualPathPrefixes = extensionLocations.ExtensionsVirtualPathPrefixes;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
@@ -42,7 +50,7 @@ namespace Orchard.FileSystems.Dependencies {
|
||||
}
|
||||
|
||||
private ActivatedExtensionDescriptor GetExtensionDescriptor(string virtualPath) {
|
||||
var prefix = PrefixMatch(virtualPath, DynamicExtensionLoader.ExtensionsVirtualPathPrefixes);
|
||||
var prefix = PrefixMatch(virtualPath, _extensionsVirtualPathPrefixes);
|
||||
if (prefix == null)
|
||||
return null;
|
||||
|
||||
|
@@ -17,8 +17,8 @@ namespace Orchard.Localization.Services {
|
||||
private readonly ISignals _signals;
|
||||
|
||||
const string CoreLocalizationFilePathFormat = "~/Core/App_Data/Localization/{0}/orchard.core.po";
|
||||
const string ModulesLocalizationFilePathFormat = "~/Modules/{0}/App_Data/Localization/{1}/orchard.module.po";
|
||||
const string ThemesLocalizationFilePathFormat = "~/Themes/{0}/App_Data/Localization/{1}/orchard.theme.po";
|
||||
const string ModulesLocalizationFilePathFormat = "{0}/App_Data/Localization/{1}/orchard.module.po";
|
||||
const string ThemesLocalizationFilePathFormat = "{0}/App_Data/Localization/{1}/orchard.theme.po";
|
||||
const string RootLocalizationFilePathFormat = "~/App_Data/Localization/{0}/orchard.root.po";
|
||||
const string TenantLocalizationFilePathFormat = "~/App_Data/Sites/{0}/Localization/{1}/orchard.po";
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace Orchard.Localization.Services {
|
||||
|
||||
foreach (var module in _extensionManager.AvailableExtensions()) {
|
||||
if (DefaultExtensionTypes.IsModule(module.ExtensionType)) {
|
||||
string modulePath = string.Format(ModulesLocalizationFilePathFormat, module.Id, culture);
|
||||
string modulePath = string.Format(ModulesLocalizationFilePathFormat, module.VirtualPath, culture);
|
||||
text = _webSiteFolder.ReadFile(modulePath);
|
||||
if (text != null) {
|
||||
_localizationStreamParser.ParseLocalizationStream(text, translations, true);
|
||||
@@ -139,7 +139,7 @@ namespace Orchard.Localization.Services {
|
||||
|
||||
foreach (var theme in _extensionManager.AvailableExtensions()) {
|
||||
if (DefaultExtensionTypes.IsTheme(theme.ExtensionType)) {
|
||||
string themePath = string.Format(ThemesLocalizationFilePathFormat, theme.Id, culture);
|
||||
string themePath = string.Format(ThemesLocalizationFilePathFormat, theme.VirtualPath, culture);
|
||||
text = _webSiteFolder.ReadFile(themePath);
|
||||
if (text != null) {
|
||||
_localizationStreamParser.ParseLocalizationStream(text, translations, true);
|
||||
|
@@ -8,6 +8,7 @@ namespace Orchard.Mvc.ViewEngines {
|
||||
|
||||
public class CreateModulesViewEngineParams {
|
||||
public IEnumerable<string> VirtualPaths { get; set; }
|
||||
public IEnumerable<string> ExtensionLocations { get; set; }
|
||||
}
|
||||
|
||||
public interface IViewEngineProvider : ISingletonDependency {
|
||||
|
@@ -59,11 +59,8 @@ namespace Orchard.Mvc.ViewEngines.Razor {
|
||||
}
|
||||
|
||||
public IViewEngine CreateModulesViewEngine(CreateModulesViewEngineParams parameters) {
|
||||
var areaFormats = new[] {
|
||||
"~/Core/{2}/Views/{1}/{0}.cshtml",
|
||||
"~/Modules/{2}/Views/{1}/{0}.cshtml",
|
||||
"~/Themes/{2}/Views/{1}/{0}.cshtml",
|
||||
};
|
||||
//TBD: It would probably be better to determined the area deterministically from the module of the controller, not by trial and error.
|
||||
var areaFormats = parameters.ExtensionLocations.Select(location => location + "/{2}/Views/{1}/{0}.cshtml").ToArray();
|
||||
|
||||
//Logger.Debug("AreaFormats (module): \r\n\t-{0}", string.Join("\r\n\t-", areaFormats));
|
||||
|
||||
|
@@ -113,6 +113,9 @@ namespace Orchard.Mvc.ViewEngines.Razor {
|
||||
}
|
||||
}
|
||||
|
||||
private string[] _commonLocations;
|
||||
public string[] CommonLocations { get { return _commonLocations ?? (_commonLocations = WorkContext.Resolve<ExtensionLocations>().CommonLocations); } }
|
||||
|
||||
public void RegisterImageSet(string imageSet, string style = "", int size = 16) {
|
||||
// hack to fake the style "alternate" for now so we don't have to change stylesheet names when this is hooked up
|
||||
// todo: (heskew) deal in shapes so we have real alternates
|
||||
@@ -199,16 +202,11 @@ namespace Orchard.Mvc.ViewEngines.Razor {
|
||||
_tenantPrefix = WorkContext.Resolve<ShellSettings>().RequestUrlPrefix ?? "";
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(_tenantPrefix)) {
|
||||
|
||||
if (path.StartsWith("~/")
|
||||
&& !path.StartsWith("~/Modules", StringComparison.OrdinalIgnoreCase)
|
||||
&& !path.StartsWith("~/Themes", StringComparison.OrdinalIgnoreCase)
|
||||
&& !path.StartsWith("~/Media", StringComparison.OrdinalIgnoreCase)
|
||||
&& !path.StartsWith("~/Core", StringComparison.OrdinalIgnoreCase)) {
|
||||
|
||||
return base.Href("~/" + _tenantPrefix + path.Substring(String.IsNullOrWhiteSpace(_tenantPrefix) ? 2 : 1), pathParts);
|
||||
}
|
||||
if (!String.IsNullOrEmpty(_tenantPrefix)
|
||||
&& path.StartsWith("~/")
|
||||
&& !CommonLocations.Any(gpp=>path.StartsWith(gpp, StringComparison.OrdinalIgnoreCase))
|
||||
) {
|
||||
return base.Href("~/" + _tenantPrefix + path.Substring(2), pathParts);
|
||||
}
|
||||
|
||||
return base.Href(path, pathParts);
|
||||
|
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Descriptor.Models;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
@@ -93,12 +94,17 @@ namespace Orchard.Mvc.ViewEngines.ThemeAwareness {
|
||||
.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)
|
||||
var moduleVirtualPaths = enabledModules
|
||||
.Select(fd => fd.Extension.VirtualPath)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase) // is Distinct guaranty to keep order?
|
||||
.ToList();
|
||||
|
||||
var moduleParams = new CreateModulesViewEngineParams { VirtualPaths = allLocations };
|
||||
var moduleLocations = enabledModules
|
||||
.Select(fd => fd.Extension.Location)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
|
||||
var moduleParams = new CreateModulesViewEngineParams { VirtualPaths = moduleVirtualPaths, ExtensionLocations = moduleLocations };
|
||||
engines = engines.Concat(_viewEngineProviders.Select(vep => vep.CreateModulesViewEngine(moduleParams)));
|
||||
|
||||
return new ViewEngineCollectionWrapper(engines);
|
||||
|
@@ -150,6 +150,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BackgroundHttpContextFactory.cs" />
|
||||
<Compile Include="Environment\Configuration\ExtensionLocations.cs" />
|
||||
<Compile Include="DisplayManagement\IPositioned.cs" />
|
||||
<Compile Include="DisplayManagement\PositionWrapper.cs" />
|
||||
<Compile Include="Localization\Services\ILocalizationStreamParser.cs" />
|
||||
|
Reference in New Issue
Block a user