mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Preparing to put a content part placement subsystem in effect
ContentShapeResult.Apply calls through the context.FindPlacement to acquire placement location DefaultContentDisplay component wires the FindPlacement onto the ShapeDescriptor.Placement ShapeDescriptor.Placement func contains the chained per-theme rule stack for part shape placement Next up - simple Placement.txt parser to convert rules into Placement chain --HG-- branch : composition
This commit is contained in:
@@ -79,5 +79,67 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
|
|||||||
Assert.That(foo.Displaying.Single(), Is.SameAs(cb3));
|
Assert.That(foo.Displaying.Single(), Is.SameAs(cb3));
|
||||||
Assert.That(foo.Displayed.Single(), Is.SameAs(cb4));
|
Assert.That(foo.Displayed.Single(), Is.SameAs(cb4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void DefaultPlacementIsReturnedByDefault() {
|
||||||
|
var manager = _container.Resolve<IShapeTableManager>();
|
||||||
|
|
||||||
|
var hello = manager.GetShapeTable(null).Descriptors["Hello"];
|
||||||
|
hello.DefaultPlacement = "Header:5";
|
||||||
|
var result = hello.Placement(null);
|
||||||
|
Assert.That(result, Is.EqualTo("Header:5"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void DescribedPlacementIsReturnedIfNotNull() {
|
||||||
|
|
||||||
|
_container.Resolve<TestShapeProvider>().Discover =
|
||||||
|
builder => builder.Describe("Hello")
|
||||||
|
.Placement(ctx => ctx.DisplayType == "Detail" ? "Main" : null)
|
||||||
|
.Placement(ctx => ctx.DisplayType == "Summary" ? "" : null);
|
||||||
|
|
||||||
|
var manager = _container.Resolve<IShapeTableManager>();
|
||||||
|
var hello = manager.GetShapeTable(null).Descriptors["Hello"];
|
||||||
|
var result1 = hello.Placement(new ShapePlacementContext { DisplayType = "Detail" });
|
||||||
|
var result2 = hello.Placement(new ShapePlacementContext { DisplayType = "Summary" });
|
||||||
|
var result3 = hello.Placement(new ShapePlacementContext { DisplayType = "Tile" });
|
||||||
|
hello.DefaultPlacement = "Header:5";
|
||||||
|
var result4 = hello.Placement(new ShapePlacementContext { DisplayType = "Detail" });
|
||||||
|
var result5 = hello.Placement(new ShapePlacementContext { DisplayType = "Summary" });
|
||||||
|
var result6 = hello.Placement(new ShapePlacementContext { DisplayType = "Tile" });
|
||||||
|
|
||||||
|
Assert.That(result1, Is.EqualTo("Main"));
|
||||||
|
Assert.That(result2, Is.EqualTo(""));
|
||||||
|
Assert.That(result3, Is.Null);
|
||||||
|
Assert.That(result4, Is.EqualTo("Main"));
|
||||||
|
Assert.That(result5, Is.EqualTo(""));
|
||||||
|
Assert.That(result6, Is.EqualTo("Header:5"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TwoArgumentVariationDoesSameThing() {
|
||||||
|
|
||||||
|
_container.Resolve<TestShapeProvider>().Discover =
|
||||||
|
builder => builder.Describe("Hello")
|
||||||
|
.Placement(ctx => ctx.DisplayType == "Detail", "Main")
|
||||||
|
.Placement(ctx => ctx.DisplayType == "Summary", "");
|
||||||
|
|
||||||
|
var manager = _container.Resolve<IShapeTableManager>();
|
||||||
|
var hello = manager.GetShapeTable(null).Descriptors["Hello"];
|
||||||
|
var result1 = hello.Placement(new ShapePlacementContext { DisplayType = "Detail" });
|
||||||
|
var result2 = hello.Placement(new ShapePlacementContext { DisplayType = "Summary" });
|
||||||
|
var result3 = hello.Placement(new ShapePlacementContext { DisplayType = "Tile" });
|
||||||
|
hello.DefaultPlacement = "Header:5";
|
||||||
|
var result4 = hello.Placement(new ShapePlacementContext { DisplayType = "Detail" });
|
||||||
|
var result5 = hello.Placement(new ShapePlacementContext { DisplayType = "Summary" });
|
||||||
|
var result6 = hello.Placement(new ShapePlacementContext { DisplayType = "Tile" });
|
||||||
|
|
||||||
|
Assert.That(result1, Is.EqualTo("Main"));
|
||||||
|
Assert.That(result2, Is.EqualTo(""));
|
||||||
|
Assert.That(result3, Is.Null);
|
||||||
|
Assert.That(result4, Is.EqualTo("Main"));
|
||||||
|
Assert.That(result5, Is.EqualTo(""));
|
||||||
|
Assert.That(result6, Is.EqualTo("Header:5"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -34,19 +34,17 @@ namespace Orchard.Core.Common.Drivers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override DriverResult Display(BodyPart part, string displayType, dynamic shapeHelper) {
|
protected override DriverResult Display(BodyPart part, string displayType, dynamic shapeHelper) {
|
||||||
var bodyText = _htmlFilters.Aggregate(part.Text, (text, filter) => filter.ProcessContent(text));
|
|
||||||
var body = shapeHelper.Parts_Common_Body(ContentPart: part, Html: new HtmlString(bodyText));
|
|
||||||
if (!string.IsNullOrWhiteSpace(displayType))
|
|
||||||
body.Metadata.Type = string.Format("{0}.{1}", body.Metadata.Type, displayType);
|
|
||||||
var location = part.GetLocation(displayType);
|
|
||||||
|
|
||||||
//return Combined(
|
return Combined(
|
||||||
// Services.Authorizer.Authorize(Permissions.ChangeOwner) ? ContentPartTemplate(model, "Parts/Common.Body.ManageWrapperPre").LongestMatch(displayType, "SummaryAdmin").Location(location) : null,
|
ContentShape("Parts_Common_Body", displayType == "Detail" ? "Content" : null, () => {
|
||||||
// Services.Authorizer.Authorize(Permissions.ChangeOwner) ? ContentPartTemplate(model, "Parts/Common.Body.Manage").LongestMatch(displayType, "SummaryAdmin").Location(location) : null,
|
var bodyText = _htmlFilters.Aggregate(part.Text, (text, filter) => filter.ProcessContent(text));
|
||||||
// ContentPartTemplate(model, TemplateName, Prefix).LongestMatch(displayType, "Summary", "SummaryAdmin").Location(location),
|
return shapeHelper.Parts_Common_Body(ContentPart: part, Html: new HtmlString(bodyText));
|
||||||
// Services.Authorizer.Authorize(Permissions.ChangeOwner) ? ContentPartTemplate(model, "Parts/Common.Body.ManageWrapperPost").LongestMatch(displayType, "SummaryAdmin").Location(location) : null);
|
}),
|
||||||
|
ContentShape("Parts_Common_Body_Summary", displayType == "Summary" ? "Content" : null, () => {
|
||||||
return ContentShape(body).Location(location);
|
var bodyText = _htmlFilters.Aggregate(part.Text, (text, filter) => filter.ProcessContent(text));
|
||||||
|
return shapeHelper.Parts_Common_Body_Summary(ContentPart: part, Html: new HtmlString(bodyText));
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override DriverResult Editor(BodyPart part, dynamic shapeHelper) {
|
protected override DriverResult Editor(BodyPart part, dynamic shapeHelper) {
|
||||||
|
@@ -3,6 +3,6 @@
|
|||||||
@Display(Model.Header)
|
@Display(Model.Header)
|
||||||
</header>
|
</header>
|
||||||
<section>
|
<section>
|
||||||
@Display(Model.Primary)
|
@Display(Model.Content)
|
||||||
</section>
|
</section>
|
||||||
</article>
|
</article>
|
@@ -45,11 +45,7 @@ namespace Orchard.Core.Routable.Drivers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override DriverResult Display(RoutePart part, string displayType, dynamic shapeHelper) {
|
protected override DriverResult Display(RoutePart part, string displayType, dynamic shapeHelper) {
|
||||||
var routePart = shapeHelper.Parts_RoutableTitle(ContentPart: part, Title: part.Title);
|
return ContentShape("Parts_RoutableTitle", "Header:5", () => shapeHelper.Parts_RoutableTitle(ContentPart: part, Title: part.Title));
|
||||||
if (!string.IsNullOrWhiteSpace(displayType))
|
|
||||||
routePart.Metadata.Type = string.Format("{0}.{1}", routePart.Metadata.Type, displayType);
|
|
||||||
var location = part.GetLocation(displayType, "Header", "5");
|
|
||||||
return ContentShape(routePart).Location(location);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override DriverResult Editor(RoutePart part, dynamic shapeHelper) {
|
protected override DriverResult Editor(RoutePart part, dynamic shapeHelper) {
|
||||||
@@ -80,7 +76,7 @@ namespace Orchard.Core.Routable.Drivers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override DriverResult Editor(RoutePart part, IUpdateModel updater, dynamic shapeHelper) {
|
protected override DriverResult Editor(RoutePart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||||
|
|
||||||
var model = new RoutableEditorViewModel();
|
var model = new RoutableEditorViewModel();
|
||||||
updater.TryUpdateModel(model, Prefix, null, null);
|
updater.TryUpdateModel(model, Prefix, null, null);
|
||||||
part.Title = model.Title;
|
part.Title = model.Title;
|
||||||
|
123
src/Orchard/ContentManagement/DefaultContentDisplay.cs
Normal file
123
src/Orchard/ContentManagement/DefaultContentDisplay.cs
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Web.Routing;
|
||||||
|
using Microsoft.CSharp.RuntimeBinder;
|
||||||
|
using Orchard.ContentManagement.Handlers;
|
||||||
|
using Orchard.DisplayManagement;
|
||||||
|
using Orchard.DisplayManagement.Descriptors;
|
||||||
|
using Orchard.Logging;
|
||||||
|
using Orchard.Mvc;
|
||||||
|
using Orchard.Themes;
|
||||||
|
|
||||||
|
namespace Orchard.ContentManagement {
|
||||||
|
public class DefaultContentDisplay : IContentDisplay {
|
||||||
|
private readonly Lazy<IEnumerable<IContentHandler>> _handlers;
|
||||||
|
private readonly IShapeHelperFactory _shapeHelperFactory;
|
||||||
|
private readonly IShapeTableManager _shapeTableManager;
|
||||||
|
private readonly IWorkContextAccessor _workContextAccessor;
|
||||||
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
|
private readonly Lazy<IThemeService> _themeService;
|
||||||
|
private readonly RequestContext _requestContext;
|
||||||
|
|
||||||
|
public DefaultContentDisplay(
|
||||||
|
Lazy<IEnumerable<IContentHandler>> handlers,
|
||||||
|
IShapeHelperFactory shapeHelperFactory,
|
||||||
|
IShapeTableManager shapeTableManager,
|
||||||
|
IWorkContextAccessor workContextAccessor,
|
||||||
|
IHttpContextAccessor httpContextAccessor,
|
||||||
|
Lazy<IThemeService> themeService,
|
||||||
|
RequestContext requestContext) {
|
||||||
|
_handlers = handlers;
|
||||||
|
_shapeHelperFactory = shapeHelperFactory;
|
||||||
|
_shapeTableManager = shapeTableManager;
|
||||||
|
_workContextAccessor = workContextAccessor;
|
||||||
|
_httpContextAccessor = httpContextAccessor;
|
||||||
|
_themeService = themeService;
|
||||||
|
_requestContext = requestContext;
|
||||||
|
Logger = NullLogger.Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
|
static readonly CallSiteCollection _shapeHelperCalls = new CallSiteCollection(shapeTypeName => Binder.InvokeMember(
|
||||||
|
CSharpBinderFlags.None,
|
||||||
|
shapeTypeName,
|
||||||
|
Enumerable.Empty<Type>(),
|
||||||
|
null,
|
||||||
|
new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
|
||||||
|
|
||||||
|
|
||||||
|
public dynamic BuildDisplay(IContent content, string displayType) {
|
||||||
|
var contentTypeDefinition = content.ContentItem.TypeDefinition;
|
||||||
|
string stereotype;
|
||||||
|
if (!contentTypeDefinition.Settings.TryGetValue("Stereotype", out stereotype))
|
||||||
|
stereotype = "Content";
|
||||||
|
|
||||||
|
var shapeTypeName = "Items_" + stereotype;
|
||||||
|
var shapeDisplayType = string.IsNullOrWhiteSpace(displayType) ? "Detail" : displayType;
|
||||||
|
|
||||||
|
var shapeHelper = _shapeHelperFactory.CreateHelper();
|
||||||
|
var itemShape = _shapeHelperCalls.Invoke(shapeHelper, shapeTypeName);
|
||||||
|
|
||||||
|
itemShape.ContentItem = content.ContentItem;
|
||||||
|
itemShape.Metadata.DisplayType = shapeDisplayType;
|
||||||
|
|
||||||
|
var context = new BuildDisplayContext(itemShape, content, shapeDisplayType, _shapeHelperFactory);
|
||||||
|
BindPlacement(context, displayType);
|
||||||
|
|
||||||
|
_handlers.Value.Invoke(handler => handler.BuildDisplay(context), Logger);
|
||||||
|
return context.Shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
public dynamic BuildEditor(IContent content) {
|
||||||
|
var shapeHelper = _shapeHelperFactory.CreateHelper();
|
||||||
|
var itemShape = shapeHelper.Items_Content_Edit();
|
||||||
|
|
||||||
|
IContent iContent = content;
|
||||||
|
if (iContent != null)
|
||||||
|
itemShape.ContentItem = iContent.ContentItem;
|
||||||
|
|
||||||
|
var context = new BuildEditorContext(itemShape, content, _shapeHelperFactory);
|
||||||
|
BindPlacement(context, null);
|
||||||
|
|
||||||
|
_handlers.Value.Invoke(handler => handler.BuildEditor(context), Logger);
|
||||||
|
return context.Shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
public dynamic UpdateEditor(IContent content, IUpdateModel updater) {
|
||||||
|
var shapeHelper = _shapeHelperFactory.CreateHelper();
|
||||||
|
var itemShape = shapeHelper.Items_Content_Edit();
|
||||||
|
|
||||||
|
IContent iContent = content;
|
||||||
|
if (iContent != null)
|
||||||
|
itemShape.ContentItem = iContent.ContentItem;
|
||||||
|
|
||||||
|
var context = new UpdateEditorContext(itemShape, content, updater, _shapeHelperFactory);
|
||||||
|
BindPlacement(context, null);
|
||||||
|
|
||||||
|
_handlers.Value.Invoke(handler => handler.UpdateEditor(context), Logger);
|
||||||
|
return context.Shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BindPlacement(BuildShapeContext context, string displayType) {
|
||||||
|
context.FindPlacement = (partShapeType, defaultLocation) => {
|
||||||
|
//var workContext = _workContextAccessor.GetContext();
|
||||||
|
//var theme = workContext.CurrentTheme;
|
||||||
|
var theme = _themeService.Value.GetRequestTheme(_requestContext);
|
||||||
|
var shapeTable = _shapeTableManager.GetShapeTable(theme.ThemeName);
|
||||||
|
ShapeDescriptor descriptor;
|
||||||
|
if (shapeTable.Descriptors.TryGetValue(partShapeType, out descriptor)) {
|
||||||
|
var placementContext = new ShapePlacementContext {
|
||||||
|
ContentType = context.ContentItem.ContentType,
|
||||||
|
DisplayType = displayType
|
||||||
|
};
|
||||||
|
var location = descriptor.Placement(placementContext);
|
||||||
|
return location ?? defaultLocation;
|
||||||
|
}
|
||||||
|
return defaultLocation;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -4,14 +4,12 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using Microsoft.CSharp.RuntimeBinder;
|
|
||||||
using Orchard.ContentManagement.Handlers;
|
using Orchard.ContentManagement.Handlers;
|
||||||
using Orchard.ContentManagement.MetaData;
|
using Orchard.ContentManagement.MetaData;
|
||||||
using Orchard.ContentManagement.MetaData.Builders;
|
using Orchard.ContentManagement.MetaData.Builders;
|
||||||
using Orchard.ContentManagement.MetaData.Models;
|
using Orchard.ContentManagement.MetaData.Models;
|
||||||
using Orchard.ContentManagement.Records;
|
using Orchard.ContentManagement.Records;
|
||||||
using Orchard.Data;
|
using Orchard.Data;
|
||||||
using Orchard.DisplayManagement;
|
|
||||||
using Orchard.Indexing;
|
using Orchard.Indexing;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
|
|
||||||
@@ -23,7 +21,7 @@ namespace Orchard.ContentManagement {
|
|||||||
private readonly IRepository<ContentItemVersionRecord> _contentItemVersionRepository;
|
private readonly IRepository<ContentItemVersionRecord> _contentItemVersionRepository;
|
||||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||||
private readonly Func<IContentManagerSession> _contentManagerSession;
|
private readonly Func<IContentManagerSession> _contentManagerSession;
|
||||||
private readonly IShapeHelperFactory _shapeHelperFactory;
|
private readonly IContentDisplay _contentDisplay;
|
||||||
|
|
||||||
public DefaultContentManager(
|
public DefaultContentManager(
|
||||||
IComponentContext context,
|
IComponentContext context,
|
||||||
@@ -32,14 +30,14 @@ namespace Orchard.ContentManagement {
|
|||||||
IRepository<ContentItemVersionRecord> contentItemVersionRepository,
|
IRepository<ContentItemVersionRecord> contentItemVersionRepository,
|
||||||
IContentDefinitionManager contentDefinitionManager,
|
IContentDefinitionManager contentDefinitionManager,
|
||||||
Func<IContentManagerSession> contentManagerSession,
|
Func<IContentManagerSession> contentManagerSession,
|
||||||
IShapeHelperFactory shapeHelperFactory) {
|
IContentDisplay contentDisplay) {
|
||||||
_context = context;
|
_context = context;
|
||||||
_contentTypeRepository = contentTypeRepository;
|
_contentTypeRepository = contentTypeRepository;
|
||||||
_contentItemRepository = contentItemRepository;
|
_contentItemRepository = contentItemRepository;
|
||||||
_contentItemVersionRepository = contentItemVersionRepository;
|
_contentItemVersionRepository = contentItemVersionRepository;
|
||||||
_contentDefinitionManager = contentDefinitionManager;
|
_contentDefinitionManager = contentDefinitionManager;
|
||||||
_contentManagerSession = contentManagerSession;
|
_contentManagerSession = contentManagerSession;
|
||||||
_shapeHelperFactory = shapeHelperFactory;
|
_contentDisplay = contentDisplay;
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,59 +368,17 @@ namespace Orchard.ContentManagement {
|
|||||||
return context.Metadata;
|
return context.Metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
static readonly CallSiteCollection _shapeHelperCalls = new CallSiteCollection(shapeTypeName => Binder.InvokeMember(
|
|
||||||
CSharpBinderFlags.None,
|
|
||||||
shapeTypeName,
|
|
||||||
Enumerable.Empty<Type>(),
|
|
||||||
null,
|
|
||||||
new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
|
|
||||||
|
|
||||||
|
|
||||||
public dynamic BuildDisplay(IContent content, string displayType = "") {
|
public dynamic BuildDisplay(IContent content, string displayType = "") {
|
||||||
var contentTypeDefinition = content.ContentItem.TypeDefinition;
|
return _contentDisplay.BuildDisplay(content, displayType);
|
||||||
string stereotype;
|
|
||||||
if (!contentTypeDefinition.Settings.TryGetValue("Stereotype", out stereotype))
|
|
||||||
stereotype = "Content";
|
|
||||||
|
|
||||||
var shapeTypeName = "Items_" + stereotype;
|
|
||||||
var shapeDisplayType = string.IsNullOrWhiteSpace(displayType) ? "Detail" : displayType;
|
|
||||||
|
|
||||||
var shapeHelper = _shapeHelperFactory.CreateHelper();
|
|
||||||
var itemShape = _shapeHelperCalls.Invoke(shapeHelper, shapeTypeName);
|
|
||||||
|
|
||||||
itemShape.ContentItem = content.ContentItem;
|
|
||||||
itemShape.Metadata.DisplayType = shapeDisplayType;
|
|
||||||
|
|
||||||
var context = new BuildDisplayContext(itemShape, content, shapeDisplayType, _shapeHelperFactory);
|
|
||||||
Handlers.Invoke(handler => handler.BuildDisplay(context), Logger);
|
|
||||||
return context.Shape;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public dynamic BuildEditor(IContent content) {
|
public dynamic BuildEditor(IContent content) {
|
||||||
var shapeHelper = _shapeHelperFactory.CreateHelper();
|
return _contentDisplay.BuildEditor(content);
|
||||||
var itemShape = shapeHelper.Items_Content_Edit();
|
|
||||||
|
|
||||||
IContent iContent = content;
|
|
||||||
if (iContent != null)
|
|
||||||
itemShape.ContentItem = iContent.ContentItem;
|
|
||||||
|
|
||||||
var context = new BuildEditorContext(itemShape, content, _shapeHelperFactory);
|
|
||||||
Handlers.Invoke(handler => handler.BuildEditor(context), Logger);
|
|
||||||
return context.Shape;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public dynamic UpdateEditor(IContent content, IUpdateModel updater) {
|
public dynamic UpdateEditor(IContent content, IUpdateModel updater) {
|
||||||
var shapeHelper = _shapeHelperFactory.CreateHelper();
|
return _contentDisplay.UpdateEditor(content, updater);
|
||||||
var itemShape = shapeHelper.Items_Content_Edit();
|
|
||||||
|
|
||||||
IContent iContent = content;
|
|
||||||
if (iContent != null)
|
|
||||||
itemShape.ContentItem = iContent.ContentItem;
|
|
||||||
|
|
||||||
var context = new UpdateEditorContext(itemShape, content, updater, _shapeHelperFactory);
|
|
||||||
Handlers.Invoke(handler => handler.UpdateEditor(context), Logger);
|
|
||||||
return context.Shape;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IContentQuery<ContentItem> Query() {
|
public IContentQuery<ContentItem> Query() {
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Orchard.ContentManagement.Handlers;
|
using Orchard.ContentManagement.Handlers;
|
||||||
using Orchard.ContentManagement.MetaData;
|
using Orchard.ContentManagement.MetaData;
|
||||||
|
using Orchard.DisplayManagement;
|
||||||
|
|
||||||
namespace Orchard.ContentManagement.Drivers {
|
namespace Orchard.ContentManagement.Drivers {
|
||||||
public abstract class ContentPartDriver<TContent> : IContentPartDriver where TContent : ContentPart, new() {
|
public abstract class ContentPartDriver<TContent> : IContentPartDriver where TContent : ContentPart, new() {
|
||||||
@@ -27,8 +28,21 @@ namespace Orchard.ContentManagement.Drivers {
|
|||||||
protected virtual DriverResult Editor(TContent part, dynamic shapeHelper) { return null; }
|
protected virtual DriverResult Editor(TContent part, dynamic shapeHelper) { return null; }
|
||||||
protected virtual DriverResult Editor(TContent part, IUpdateModel updater, dynamic shapeHelper) { return null; }
|
protected virtual DriverResult Editor(TContent part, IUpdateModel updater, dynamic shapeHelper) { return null; }
|
||||||
|
|
||||||
public ContentShapeResult ContentShape(dynamic shape) {
|
[Obsolete("Provided while transitioning to factory variations")]
|
||||||
return new ContentShapeResult(shape, Prefix).Location(Zone);
|
public ContentShapeResult ContentShape(IShape shape) {
|
||||||
|
return ContentShapeImplementation(shape.Metadata.Type, Zone, () => shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContentShapeResult ContentShape(string shapeType, Func<dynamic> factory) {
|
||||||
|
return ContentShapeImplementation(shapeType, null, factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContentShapeResult ContentShape(string shapeType, string defaultLocation, Func<dynamic> factory) {
|
||||||
|
return ContentShapeImplementation(shapeType, defaultLocation, factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContentShapeResult ContentShapeImplementation(string shapeType, string defaultLocation, Func<object> factory) {
|
||||||
|
return new ContentShapeResult(shapeType, Prefix, factory).Location(defaultLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete]
|
[Obsolete]
|
||||||
|
@@ -1,37 +1,57 @@
|
|||||||
using Orchard.ContentManagement.Handlers;
|
using System;
|
||||||
|
using Orchard.ContentManagement.Handlers;
|
||||||
using Orchard.DisplayManagement;
|
using Orchard.DisplayManagement;
|
||||||
|
using Orchard.DisplayManagement.Shapes;
|
||||||
|
|
||||||
namespace Orchard.ContentManagement.Drivers {
|
namespace Orchard.ContentManagement.Drivers {
|
||||||
public class ContentShapeResult : DriverResult {
|
public class ContentShapeResult : DriverResult {
|
||||||
public dynamic Shape { get; set; }
|
private string _defaultLocation;
|
||||||
public string Prefix { get; set; }
|
private readonly string _shapeType;
|
||||||
public string Zone { get; set; }
|
private readonly string _prefix;
|
||||||
public string Position { get; set; }
|
private readonly Func<dynamic> _shapeBuilder;
|
||||||
|
|
||||||
public ContentShapeResult(dynamic shape, string prefix) {
|
public ContentShapeResult(string shapeType, string prefix, Func<dynamic> shapeBuilder) {
|
||||||
Shape = shape;
|
_shapeType = shapeType;
|
||||||
Prefix = prefix;
|
_prefix = prefix;
|
||||||
|
_shapeBuilder = shapeBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Apply(BuildDisplayContext context) {
|
public override void Apply(BuildDisplayContext context) {
|
||||||
context.Shape.Zones[Zone].Add(Shape, Position);
|
ApplyImplementation(context, context.DisplayType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Apply(BuildEditorContext context) {
|
public override void Apply(BuildEditorContext context) {
|
||||||
IShape iShape = Shape;
|
ApplyImplementation(context, null);
|
||||||
if (iShape != null )
|
}
|
||||||
Shape.Metadata.Prefix = Prefix;
|
|
||||||
context.Shape.Zones[Zone].Add(Shape, Position);
|
private void ApplyImplementation(BuildShapeContext context, string displayType) {
|
||||||
|
var location = context.FindPlacement(_shapeType, _defaultLocation);
|
||||||
|
if (string.IsNullOrEmpty(location) || location == "-")
|
||||||
|
return;
|
||||||
|
|
||||||
|
dynamic parentShape = context.Shape;
|
||||||
|
IShape contentShape = _shapeBuilder();
|
||||||
|
contentShape.Metadata.Prefix = _prefix;
|
||||||
|
contentShape.Metadata.DisplayType = displayType;
|
||||||
|
|
||||||
|
var delimiterIndex = location.IndexOf(':');
|
||||||
|
if (delimiterIndex < 0) {
|
||||||
|
parentShape.Zones[location].Add(contentShape);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var zoneName = location.Substring(0, delimiterIndex);
|
||||||
|
var position = location.Substring(delimiterIndex + 1);
|
||||||
|
parentShape.Zones[zoneName].Add(contentShape, position);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentShapeResult Location(string zone) {
|
public ContentShapeResult Location(string zone) {
|
||||||
Zone = zone;
|
_defaultLocation = zone;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentShapeResult Location(string zone, string position) {
|
public ContentShapeResult Location(string zone, string position) {
|
||||||
Zone = zone;
|
_defaultLocation = zone + ":" + position;
|
||||||
Position = position;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using Orchard.DisplayManagement;
|
using Orchard.DisplayManagement;
|
||||||
|
|
||||||
namespace Orchard.ContentManagement.Handlers {
|
namespace Orchard.ContentManagement.Handlers {
|
||||||
@@ -6,10 +7,13 @@ namespace Orchard.ContentManagement.Handlers {
|
|||||||
Shape = shape;
|
Shape = shape;
|
||||||
ContentItem = content.ContentItem;
|
ContentItem = content.ContentItem;
|
||||||
New = shapeHelperFactory.CreateHelper();
|
New = shapeHelperFactory.CreateHelper();
|
||||||
|
FindPlacement = (partType, defaultLocation) => defaultLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public dynamic Shape { get; private set; }
|
public dynamic Shape { get; private set; }
|
||||||
public ContentItem ContentItem { get; private set; }
|
public ContentItem ContentItem { get; private set; }
|
||||||
public dynamic New { get; private set; }
|
public dynamic New { get; private set; }
|
||||||
|
|
||||||
|
public Func<string, string, string> FindPlacement { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -31,6 +31,12 @@ namespace Orchard.ContentManagement {
|
|||||||
dynamic UpdateEditor(IContent content, IUpdateModel updater);
|
dynamic UpdateEditor(IContent content, IUpdateModel updater);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface IContentDisplay : IDependency {
|
||||||
|
dynamic BuildDisplay(IContent content, string displayType = "");
|
||||||
|
dynamic BuildEditor(IContent content);
|
||||||
|
dynamic UpdateEditor(IContent content, IUpdateModel updater);
|
||||||
|
}
|
||||||
|
|
||||||
public class VersionOptions {
|
public class VersionOptions {
|
||||||
public static VersionOptions Latest { get { return new VersionOptions { IsLatest = true }; } }
|
public static VersionOptions Latest { get { return new VersionOptions { IsLatest = true }; } }
|
||||||
public static VersionOptions Published { get { return new VersionOptions { IsPublished = true }; } }
|
public static VersionOptions Published { get { return new VersionOptions { IsPublished = true }; } }
|
||||||
|
@@ -73,7 +73,7 @@ namespace Orchard.DisplayManagement.Descriptors {
|
|||||||
descriptor.Created = existing.Concat(new[] { action });
|
descriptor.Created = existing.Concat(new[] { action });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShapeAlterationBuilder OnDisplaying(Action<ShapeDisplayingContext> action) {
|
public ShapeAlterationBuilder OnDisplaying(Action<ShapeDisplayingContext> action) {
|
||||||
return Configure(descriptor => {
|
return Configure(descriptor => {
|
||||||
var existing = descriptor.Displaying ?? Enumerable.Empty<Action<ShapeDisplayingContext>>();
|
var existing = descriptor.Displaying ?? Enumerable.Empty<Action<ShapeDisplayingContext>>();
|
||||||
@@ -88,8 +88,28 @@ namespace Orchard.DisplayManagement.Descriptors {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ShapeAlterationBuilder Placement(Func<ShapePlacementContext, string> action) {
|
||||||
|
return Configure(descriptor => {
|
||||||
|
var next = descriptor.Placement;
|
||||||
|
descriptor.Placement = ctx => action(ctx) ?? next(ctx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShapeAlterationBuilder Placement(Func<ShapePlacementContext, bool> predicate, string location) {
|
||||||
|
return Configure(descriptor => {
|
||||||
|
var next = descriptor.Placement;
|
||||||
|
descriptor.Placement = ctx => predicate(ctx) ? location : next(ctx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public ShapeAlteration Build() {
|
public ShapeAlteration Build() {
|
||||||
return new ShapeAlteration(_shapeType, _feature, _configurations.ToArray());
|
return new ShapeAlteration(_shapeType, _feature, _configurations.ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public class ShapePlacementContext {
|
||||||
|
public string ContentType { get; set; }
|
||||||
|
public string DisplayType { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -13,6 +13,7 @@ namespace Orchard.DisplayManagement.Descriptors {
|
|||||||
Displayed = Enumerable.Empty<Action<ShapeDisplayedContext>>();
|
Displayed = Enumerable.Empty<Action<ShapeDisplayedContext>>();
|
||||||
Wrappers = new List<string>();
|
Wrappers = new List<string>();
|
||||||
Bindings = new Dictionary<string, ShapeBinding>();
|
Bindings = new Dictionary<string, ShapeBinding>();
|
||||||
|
Placement = ctx => DefaultPlacement;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ShapeType { get; set; }
|
public string ShapeType { get; set; }
|
||||||
@@ -41,6 +42,9 @@ namespace Orchard.DisplayManagement.Descriptors {
|
|||||||
public IEnumerable<Action<ShapeDisplayingContext>> Displaying { get; set; }
|
public IEnumerable<Action<ShapeDisplayingContext>> Displaying { get; set; }
|
||||||
public IEnumerable<Action<ShapeDisplayedContext>> Displayed { get; set; }
|
public IEnumerable<Action<ShapeDisplayedContext>> Displayed { get; set; }
|
||||||
|
|
||||||
|
public Func<ShapePlacementContext, string> Placement { get; set; }
|
||||||
|
public string DefaultPlacement { get; set; }
|
||||||
|
|
||||||
public IList<string> Wrappers { get; set; }
|
public IList<string> Wrappers { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -159,6 +159,7 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="ContentManagement\DefaultContentDisplay.cs" />
|
||||||
<Compile Include="ContentManagement\Drivers\ContentShapeResult.cs" />
|
<Compile Include="ContentManagement\Drivers\ContentShapeResult.cs" />
|
||||||
<Compile Include="ContentManagement\Handlers\BuildShapeContext.cs" />
|
<Compile Include="ContentManagement\Handlers\BuildShapeContext.cs" />
|
||||||
<Compile Include="DisplayManagement\Descriptors\ShapeDescriptor.cs" />
|
<Compile Include="DisplayManagement\Descriptors\ShapeDescriptor.cs" />
|
||||||
|
Reference in New Issue
Block a user