2010-12-10 16:24:03 -08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Concurrent;
|
2010-08-30 16:02:20 -07:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
2010-08-30 17:10:05 -07:00
|
|
|
|
using System.Web;
|
2010-08-30 16:02:20 -07:00
|
|
|
|
using System.Web.Mvc;
|
|
|
|
|
using System.Web.Mvc.Html;
|
2010-12-03 18:37:06 -08:00
|
|
|
|
using Orchard.Caching;
|
2010-08-30 16:02:20 -07:00
|
|
|
|
using Orchard.DisplayManagement.Implementation;
|
|
|
|
|
using Orchard.Environment.Descriptor.Models;
|
|
|
|
|
using Orchard.Environment.Extensions;
|
|
|
|
|
using Orchard.Environment.Extensions.Models;
|
2010-11-30 13:19:15 -08:00
|
|
|
|
using Orchard.FileSystems.VirtualPath;
|
2010-12-10 16:24:03 -08:00
|
|
|
|
using Orchard.Logging;
|
2010-08-30 16:02:20 -07:00
|
|
|
|
|
|
|
|
|
namespace Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy {
|
2010-09-13 20:57:37 -07:00
|
|
|
|
public class ShapeTemplateBindingStrategy : IShapeTableProvider {
|
2010-08-30 16:02:20 -07:00
|
|
|
|
private readonly ShellDescriptor _shellDescriptor;
|
|
|
|
|
private readonly IExtensionManager _extensionManager;
|
2010-12-03 18:37:06 -08:00
|
|
|
|
private readonly ICacheManager _cacheManager;
|
|
|
|
|
private readonly IVirtualPathMonitor _virtualPathMonitor;
|
2010-11-30 13:19:15 -08:00
|
|
|
|
private readonly IVirtualPathProvider _virtualPathProvider;
|
2010-08-30 16:02:20 -07:00
|
|
|
|
private readonly IEnumerable<IShapeTemplateHarvester> _harvesters;
|
|
|
|
|
private readonly IEnumerable<IShapeTemplateViewEngine> _shapeTemplateViewEngines;
|
|
|
|
|
|
2010-11-30 13:19:15 -08:00
|
|
|
|
|
2010-08-30 16:02:20 -07:00
|
|
|
|
public ShapeTemplateBindingStrategy(
|
|
|
|
|
IEnumerable<IShapeTemplateHarvester> harvesters,
|
|
|
|
|
ShellDescriptor shellDescriptor,
|
|
|
|
|
IExtensionManager extensionManager,
|
2010-12-03 18:37:06 -08:00
|
|
|
|
ICacheManager cacheManager,
|
|
|
|
|
IVirtualPathMonitor virtualPathMonitor,
|
2010-11-30 13:19:15 -08:00
|
|
|
|
IVirtualPathProvider virtualPathProvider,
|
2010-08-30 16:02:20 -07:00
|
|
|
|
IEnumerable<IShapeTemplateViewEngine> shapeTemplateViewEngines) {
|
|
|
|
|
_harvesters = harvesters;
|
|
|
|
|
_shellDescriptor = shellDescriptor;
|
|
|
|
|
_extensionManager = extensionManager;
|
2010-12-03 18:37:06 -08:00
|
|
|
|
_cacheManager = cacheManager;
|
|
|
|
|
_virtualPathMonitor = virtualPathMonitor;
|
2010-11-30 13:19:15 -08:00
|
|
|
|
_virtualPathProvider = virtualPathProvider;
|
2010-08-30 16:02:20 -07:00
|
|
|
|
_shapeTemplateViewEngines = shapeTemplateViewEngines;
|
2010-12-10 16:24:03 -08:00
|
|
|
|
Logger = NullLogger.Instance;
|
2010-08-30 16:02:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
2010-12-10 16:24:03 -08:00
|
|
|
|
public ILogger Logger { get; set; }
|
|
|
|
|
|
2010-08-30 16:02:20 -07:00
|
|
|
|
private static IEnumerable<ExtensionDescriptor> Once(IEnumerable<FeatureDescriptor> featureDescriptors) {
|
|
|
|
|
var once = new ConcurrentDictionary<string, object>();
|
2010-11-18 15:37:47 -08:00
|
|
|
|
return featureDescriptors.Select(fd => fd.Extension).Where(ed => once.TryAdd(ed.Id, null)).ToList();
|
2010-08-30 16:02:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Discover(ShapeTableBuilder builder) {
|
|
|
|
|
var harvesterInfos = _harvesters.Select(harvester => new { harvester, subPaths = harvester.SubPaths() });
|
|
|
|
|
|
|
|
|
|
var availableFeatures = _extensionManager.AvailableFeatures();
|
2010-10-12 12:21:46 -07:00
|
|
|
|
var activeFeatures = availableFeatures.Where(FeatureIsEnabled);
|
2010-08-30 16:02:20 -07:00
|
|
|
|
var activeExtensions = Once(activeFeatures);
|
|
|
|
|
|
|
|
|
|
var hits = activeExtensions.SelectMany(extensionDescriptor => {
|
|
|
|
|
var pathContexts = harvesterInfos.SelectMany(harvesterInfo => harvesterInfo.subPaths.Select(subPath => {
|
2010-11-30 12:15:38 -08:00
|
|
|
|
var basePath = Path.Combine(extensionDescriptor.Location, extensionDescriptor.Id).Replace(Path.DirectorySeparatorChar, '/');
|
|
|
|
|
var virtualPath = Path.Combine(basePath, subPath).Replace(Path.DirectorySeparatorChar, '/');
|
2010-12-03 18:37:06 -08:00
|
|
|
|
var fileNames = _cacheManager.Get(virtualPath, ctx => {
|
|
|
|
|
ctx.Monitor(_virtualPathMonitor.WhenPathChanges(virtualPath));
|
|
|
|
|
return _virtualPathProvider.ListFiles(virtualPath).Select(Path.GetFileName);
|
|
|
|
|
});
|
2010-11-30 13:19:15 -08:00
|
|
|
|
return new { harvesterInfo.harvester, basePath, subPath, virtualPath, fileNames };
|
2010-08-30 16:02:20 -07:00
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
var fileContexts = pathContexts.SelectMany(pathContext => _shapeTemplateViewEngines.SelectMany(ve => {
|
2010-11-30 13:19:15 -08:00
|
|
|
|
var fileNames = ve.DetectTemplateFileNames(pathContext.fileNames);
|
2010-12-03 18:37:06 -08:00
|
|
|
|
return fileNames.Select(
|
|
|
|
|
fileName => new {
|
|
|
|
|
fileName = Path.GetFileNameWithoutExtension(fileName),
|
|
|
|
|
fileVirtualPath = Path.Combine(pathContext.virtualPath, fileName).Replace(Path.DirectorySeparatorChar, '/'),
|
|
|
|
|
pathContext
|
|
|
|
|
});
|
2010-08-30 16:02:20 -07:00
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
var shapeContexts = fileContexts.SelectMany(fileContext => {
|
|
|
|
|
var harvestShapeInfo = new HarvestShapeInfo {
|
|
|
|
|
SubPath = fileContext.pathContext.subPath,
|
|
|
|
|
FileName = fileContext.fileName,
|
|
|
|
|
TemplateVirtualPath = fileContext.fileVirtualPath
|
|
|
|
|
};
|
|
|
|
|
var harvestShapeHits = fileContext.pathContext.harvester.HarvestShape(harvestShapeInfo);
|
|
|
|
|
return harvestShapeHits.Select(harvestShapeHit => new { harvestShapeInfo, harvestShapeHit, fileContext });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return shapeContexts.Select(shapeContext => new { extensionDescriptor, shapeContext });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var iter in hits) {
|
|
|
|
|
// templates are always associated with the namesake feature of module or theme
|
|
|
|
|
var hit = iter;
|
2010-11-18 15:37:47 -08:00
|
|
|
|
var featureDescriptors = iter.extensionDescriptor.Features.Where(fd => fd.Id == hit.extensionDescriptor.Id);
|
2010-12-10 16:24:03 -08:00
|
|
|
|
foreach (var featureDescriptor in featureDescriptors) {
|
|
|
|
|
Logger.Debug("Binding {0} as shape [{1}] for feature {2}",
|
|
|
|
|
hit.shapeContext.harvestShapeInfo.TemplateVirtualPath,
|
|
|
|
|
iter.shapeContext.harvestShapeHit.ShapeType,
|
|
|
|
|
featureDescriptor.Id);
|
|
|
|
|
|
2010-09-13 20:57:37 -07:00
|
|
|
|
builder.Describe(iter.shapeContext.harvestShapeHit.ShapeType)
|
|
|
|
|
.From(new Feature { Descriptor = featureDescriptor })
|
2010-08-31 18:30:12 -07:00
|
|
|
|
.BoundAs(
|
2010-09-13 20:57:37 -07:00
|
|
|
|
hit.shapeContext.harvestShapeInfo.TemplateVirtualPath,
|
2010-08-31 18:30:12 -07:00
|
|
|
|
shapeDescriptor => displayContext => Render(shapeDescriptor, displayContext, hit.shapeContext.harvestShapeInfo, hit.shapeContext.harvestShapeHit));
|
2010-08-30 16:02:20 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-31 18:30:12 -07:00
|
|
|
|
private bool FeatureIsEnabled(FeatureDescriptor fd) {
|
2010-12-01 17:52:10 -08:00
|
|
|
|
return (DefaultExtensionTypes.IsTheme(fd.Extension.ExtensionType) && (fd.Id == "TheAdmin" || fd.Id == "SafeMode")) ||
|
2010-11-18 15:37:47 -08:00
|
|
|
|
_shellDescriptor.Features.Any(sf => sf.Name == fd.Id);
|
2010-08-31 18:30:12 -07:00
|
|
|
|
}
|
|
|
|
|
|
2010-08-30 17:10:05 -07:00
|
|
|
|
private IHtmlString Render(ShapeDescriptor shapeDescriptor, DisplayContext displayContext, HarvestShapeInfo harvestShapeInfo, HarvestShapeHit harvestShapeHit) {
|
2010-08-30 16:02:20 -07:00
|
|
|
|
var htmlHelper = new HtmlHelper(displayContext.ViewContext, displayContext.ViewDataContainer);
|
2010-08-31 18:30:12 -07:00
|
|
|
|
return htmlHelper.Partial(harvestShapeInfo.TemplateVirtualPath, displayContext.Value);
|
2010-08-30 16:02:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|