mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
@@ -10,7 +10,7 @@ Features:
|
||||
Name: Templates
|
||||
Description: Provides a Template type that represents a shape template, stored as a content item.
|
||||
Category: Content
|
||||
Dependencies: Contents, Orchard.Tokens
|
||||
Dependencies: Contents, Orchard.Tokens, Orchard.Core
|
||||
Orchard.Templates.Razor:
|
||||
Name: Razor Templates
|
||||
Description: Extends Templates with Razor templates.
|
||||
|
@@ -177,7 +177,7 @@
|
||||
<Compile Include="Services\TemplateProcessorImpl.cs" />
|
||||
<Compile Include="Services\RazorTemplateProcessor.cs" />
|
||||
<Compile Include="Services\DefaultTemplateService.cs" />
|
||||
<Compile Include="Services\TemplateShapeDisplayEvent.cs" />
|
||||
<Compile Include="Services\TemplateShapeBindingResolver.cs" />
|
||||
<Compile Include="Settings\ShapePartSettings.cs" />
|
||||
<Compile Include="Settings\ShapePartSettingsEvents.cs" />
|
||||
<Compile Include="ViewModels\ShapePartSettingsViewModel.cs" />
|
||||
|
@@ -0,0 +1,84 @@
|
||||
using Orchard.Caching;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.DisplayManagement.Implementation;
|
||||
using Orchard.Templates.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.DisplayManagement.Descriptors;
|
||||
|
||||
namespace Orchard.Templates.Services {
|
||||
public class TemplateShapeBindingResolver : IShapeBindingResolver {
|
||||
private ICacheManager _cacheManager;
|
||||
private ISignals _signals;
|
||||
private IContentManager _contentManager;
|
||||
private ITemplateService _templateService;
|
||||
|
||||
public TemplateShapeBindingResolver(
|
||||
ICacheManager cacheManager,
|
||||
ISignals signals,
|
||||
IContentManager contentManager,
|
||||
ITemplateService templateService
|
||||
) {
|
||||
_cacheManager = cacheManager;
|
||||
_signals = signals;
|
||||
_contentManager = contentManager;
|
||||
_templateService = templateService;
|
||||
}
|
||||
|
||||
public bool TryGetDescriptorBinding(string shapeType, out ShapeBinding shapeBinding) {
|
||||
var processors = BuildShapeProcessors();
|
||||
Func<dynamic, IHtmlString> processor;
|
||||
|
||||
TemplateResult templateResult = null;
|
||||
if (processors.TryGetValue(shapeType, out templateResult)) {
|
||||
shapeBinding = new ShapeBinding {
|
||||
BindingName = "Templates",
|
||||
Binding = ctx => CoerceHtmlString(_templateService.Execute(
|
||||
templateResult.Template,
|
||||
templateResult.Name,
|
||||
templateResult.Processor, ctx.Value))
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
shapeBinding = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private IDictionary<string, TemplateResult> BuildShapeProcessors() {
|
||||
return _cacheManager.Get("Template.ShapeProcessors", ctx => {
|
||||
ctx.Monitor(_signals.When(DefaultTemplateService.TemplatesSignal));
|
||||
|
||||
var allTemplates = _contentManager.Query<ShapePart>().List();
|
||||
|
||||
return allTemplates.Select(x => {
|
||||
var name = x.Name;
|
||||
var template = x.Template;
|
||||
var processorName = x.ProcessorName;
|
||||
|
||||
return new TemplateResult {
|
||||
Name = x.Name,
|
||||
Template = x.Template,
|
||||
Processor = x.ProcessorName
|
||||
};
|
||||
|
||||
}).ToDictionary(x => x.Name, x => x);
|
||||
});
|
||||
}
|
||||
|
||||
private static IHtmlString CoerceHtmlString(object invoke) {
|
||||
return invoke as IHtmlString ?? (invoke != null ? new HtmlString(invoke.ToString()) : null);
|
||||
}
|
||||
|
||||
private class TemplateResult {
|
||||
public string Name { get; set; }
|
||||
public string Processor { get; set; }
|
||||
public string Template { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,59 +0,0 @@
|
||||
using Orchard.Caching;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.DisplayManagement.Implementation;
|
||||
using Orchard.Templates.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Orchard.Templates.Services {
|
||||
public class TemplateShapeDisplayEvent : IShapeDisplayEvents {
|
||||
private ICacheManager _cacheManager;
|
||||
private ISignals _signals;
|
||||
private IContentManager _contentManager;
|
||||
private ITemplateService _templateService;
|
||||
|
||||
public TemplateShapeDisplayEvent(
|
||||
ICacheManager cacheManager,
|
||||
ISignals signals,
|
||||
IContentManager contentManager,
|
||||
ITemplateService templateService
|
||||
) {
|
||||
_cacheManager = cacheManager;
|
||||
_signals = signals;
|
||||
_contentManager = contentManager;
|
||||
_templateService = templateService;
|
||||
}
|
||||
|
||||
public void Displaying(ShapeDisplayingContext context) {
|
||||
var processors = BuildShapeProcessors();
|
||||
Func<dynamic, IHtmlString> processor;
|
||||
|
||||
if (processors.TryGetValue(context.ShapeMetadata.Type, out processor)) {
|
||||
context.ChildContent = processor(context.Shape);
|
||||
}
|
||||
}
|
||||
|
||||
public void Displayed(ShapeDisplayedContext context) {
|
||||
}
|
||||
|
||||
public IDictionary<string, Func<dynamic, IHtmlString>> BuildShapeProcessors() {
|
||||
return _cacheManager.Get("Template.ShapeProcessors", ctx => {
|
||||
ctx.Monitor(_signals.When(DefaultTemplateService.TemplatesSignal));
|
||||
|
||||
var allTemplates = _contentManager.Query<ShapePart>().List();
|
||||
|
||||
return allTemplates.Select(x => new KeyValuePair<string, Func<dynamic, IHtmlString>>(
|
||||
x.Name,
|
||||
d => CoerceHtmlString(_templateService.Execute(x.Template, x.Name, x.ProcessorName, d))
|
||||
)).ToDictionary(x => x.Key, x => x.Value);
|
||||
});
|
||||
}
|
||||
|
||||
private static IHtmlString CoerceHtmlString(object invoke) {
|
||||
return invoke as IHtmlString ?? (invoke != null ? new HtmlString(invoke.ToString()) : null);
|
||||
}
|
||||
}
|
||||
}
|
9
src/Orchard/DisplayManagement/IShapeBindingResolver.cs
Normal file
9
src/Orchard/DisplayManagement/IShapeBindingResolver.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.DisplayManagement.Descriptors;
|
||||
using Orchard.DisplayManagement.Shapes;
|
||||
|
||||
namespace Orchard.DisplayManagement {
|
||||
public interface IShapeBindingResolver : IDependency {
|
||||
bool TryGetDescriptorBinding(string shapeType, out ShapeBinding shapeBinding);
|
||||
}
|
||||
}
|
@@ -18,6 +18,7 @@ namespace Orchard.DisplayManagement.Implementation {
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IEnumerable<IShapeDisplayEvents> _shapeDisplayEvents;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IEnumerable<IShapeBindingResolver> _shapeBindingResolvers;
|
||||
|
||||
// this need to be Shape instead of IShape - cast to interface throws error on clr types like HtmlString
|
||||
private static readonly CallSite<Func<CallSite, object, Shape>> _convertAsShapeCallsite = CallSite<Func<CallSite, object, Shape>>.Create(
|
||||
@@ -30,12 +31,15 @@ namespace Orchard.DisplayManagement.Implementation {
|
||||
public DefaultDisplayManager(
|
||||
IWorkContextAccessor workContextAccessor,
|
||||
IEnumerable<IShapeDisplayEvents> shapeDisplayEvents,
|
||||
IEnumerable<IShapeBindingResolver> shapeBindingResolvers,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
Lazy<IShapeTableLocator> shapeTableLocator) {
|
||||
_shapeTableLocator = shapeTableLocator;
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_shapeDisplayEvents = shapeDisplayEvents;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_shapeBindingResolvers = shapeBindingResolvers;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
@@ -135,12 +139,19 @@ namespace Orchard.DisplayManagement.Implementation {
|
||||
return shape.Metadata.ChildContent;
|
||||
}
|
||||
|
||||
static bool TryGetDescriptorBinding(string shapeType, IEnumerable<string> shapeAlternates, ShapeTable shapeTable, out ShapeBinding shapeBinding) {
|
||||
private bool TryGetDescriptorBinding(string shapeType, IEnumerable<string> shapeAlternates, ShapeTable shapeTable, out ShapeBinding shapeBinding) {
|
||||
// shape alternates are optional, fully qualified binding names
|
||||
// the earliest added alternates have the lowest priority
|
||||
// the descriptor returned is based on the binding that is matched, so it may be an entirely
|
||||
// different descriptor if the alternate has a different base name
|
||||
foreach (var shapeAlternate in shapeAlternates.Reverse()) {
|
||||
|
||||
foreach (var shapeBindingResolver in _shapeBindingResolvers) {
|
||||
if(shapeBindingResolver.TryGetDescriptorBinding(shapeAlternate, out shapeBinding)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shapeTable.Bindings.TryGetValue(shapeAlternate, out shapeBinding)) {
|
||||
return true;
|
||||
}
|
||||
@@ -151,6 +162,12 @@ namespace Orchard.DisplayManagement.Implementation {
|
||||
// so the shapetype itself may contain a longer alternate forms that falls back to a shorter one
|
||||
var shapeTypeScan = shapeType;
|
||||
for (; ; ) {
|
||||
foreach (var shapeBindingResolver in _shapeBindingResolvers) {
|
||||
if (shapeBindingResolver.TryGetDescriptorBinding(shapeTypeScan, out shapeBinding)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shapeTable.Bindings.TryGetValue(shapeTypeScan, out shapeBinding)) {
|
||||
return true;
|
||||
}
|
||||
|
@@ -211,6 +211,7 @@
|
||||
<Compile Include="DisplayManagement\Implementation\IShapeDisplayEvents.cs" />
|
||||
<Compile Include="DisplayManagement\Implementation\IShapeFactoryEvents.cs" />
|
||||
<Compile Include="DisplayManagement\INamedEnumerable.cs" />
|
||||
<Compile Include="DisplayManagement\IShapeBindingResolver.cs" />
|
||||
<Compile Include="DisplayManagement\IShapeDisplay.cs" />
|
||||
<Compile Include="DisplayManagement\ShapeDisplay.cs" />
|
||||
<Compile Include="DisplayManagement\Shapes\Composite.cs" />
|
||||
|
Reference in New Issue
Block a user