Made shape placement parsing strategy extendable with providers (#7837)

This commit is contained in:
Carl Woodhouse
2017-09-07 20:40:49 +01:00
committed by Sébastien Ros
parent fc38e0eb5d
commit a992c1e74e
5 changed files with 85 additions and 32 deletions

View File

@@ -247,7 +247,10 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
_container.Resolve<TestShapeProvider>().Discover =
builder => builder.Describe("Hello").From(TestFeature())
.Placement(ShapePlacementParsingStrategy.BuildPredicate(c => true, new KeyValuePair<string, string>("Path", path)), new PlacementInfo { Location = "Match" });
.Placement(ShapePlacementParsingStrategy.BuildPredicate(c => true,
new KeyValuePair<string, string>("Path", path),
new[] { new PathPlacementParseMatchProvider() }),
new PlacementInfo { Location = "Match" });
var manager = _container.Resolve<IShapeTableManager>();
var hello = manager.GetShapeTable(null).Descriptors["Hello"];

View File

@@ -0,0 +1,57 @@
using System;
using System.Linq;
using System.Web;
namespace Orchard.DisplayManagement.Descriptors.ShapePlacementStrategy {
public class ContentPartPlacementParseMatchProvider : IPlacementParseMatchProvider {
public string Key { get { return "ContentPart"; } }
public bool Match(ShapePlacementContext context, string expression) {
return context.Content != null && context.Content.ContentItem.Parts.Any(part => part.PartDefinition.Name == expression);
}
}
public class ContentTypePlacementParseMatchProvider : IPlacementParseMatchProvider {
public string Key { get { return "ContentType"; } }
public bool Match(ShapePlacementContext context, string expression) {
if (expression.EndsWith("*")) {
var prefix = expression.Substring(0, expression.Length - 1);
return (context.ContentType ?? "").StartsWith(prefix) || (context.Stereotype ?? "").StartsWith(prefix);
}
return context.ContentType == expression || context.Stereotype == expression;
}
}
public class DisplayTypePlacementParseMatchProvider : IPlacementParseMatchProvider {
public string Key { get { return "DisplayType"; } }
public bool Match(ShapePlacementContext context, string expression) {
if (expression.EndsWith("*")) {
var prefix = expression.Substring(0, expression.Length - 1);
return (context.DisplayType ?? "").StartsWith(prefix);
}
return context.DisplayType == expression;
}
}
public class PathPlacementParseMatchProvider : IPlacementParseMatchProvider {
public string Key { get { return "Path"; } }
public bool Match(ShapePlacementContext context, string expression) {
var normalizedPath = VirtualPathUtility.IsAbsolute(expression)
? VirtualPathUtility.ToAppRelative(expression)
: VirtualPathUtility.Combine("~/", expression);
if (normalizedPath.EndsWith("*")) {
var prefix = normalizedPath.Substring(0, normalizedPath.Length - 1);
return VirtualPathUtility.ToAppRelative(string.IsNullOrEmpty(context.Path) ? "/" : context.Path).StartsWith(prefix, StringComparison.OrdinalIgnoreCase);
}
normalizedPath = VirtualPathUtility.AppendTrailingSlash(normalizedPath);
return context.Path.Equals(normalizedPath, StringComparison.OrdinalIgnoreCase);
}
}
}

View File

@@ -0,0 +1,6 @@
namespace Orchard.DisplayManagement.Descriptors.ShapePlacementStrategy {
public interface IPlacementParseMatchProvider : IDependency {
string Key { get; }
bool Match(ShapePlacementContext context, string expression);
}
}

View File

@@ -2,7 +2,6 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Orchard.Environment.Descriptor.Models;
using Orchard.Environment.Extensions;
using Orchard.Environment.Extensions.Models;
@@ -15,14 +14,17 @@ namespace Orchard.DisplayManagement.Descriptors.ShapePlacementStrategy {
private readonly IExtensionManager _extensionManager;
private readonly ShellDescriptor _shellDescriptor;
private readonly IPlacementFileParser _placementFileParser;
private readonly IEnumerable<IPlacementParseMatchProvider> _placementParseMatchProviders;
public ShapePlacementParsingStrategy(
IExtensionManager extensionManager,
ShellDescriptor shellDescriptor,
IPlacementFileParser placementFileParser) {
IPlacementFileParser placementFileParser,
IEnumerable<IPlacementParseMatchProvider> placementParseMatchProviders) {
_extensionManager = extensionManager;
_shellDescriptor = shellDescriptor;
_placementFileParser = placementFileParser;
_placementParseMatchProviders = placementParseMatchProviders;
}
public void Discover(ShapeTableBuilder builder) {
@@ -125,37 +127,20 @@ namespace Orchard.DisplayManagement.Descriptors.ShapePlacementStrategy {
}
}
public static Func<ShapePlacementContext, bool> BuildPredicate(Func<ShapePlacementContext, bool> predicate, KeyValuePair<string, string> term) {
var expression = term.Value;
switch (term.Key) {
case "ContentPart":
return ctx => ctx.Content != null
&& ctx.Content.ContentItem.Parts.Any(part => part.PartDefinition.Name == expression)
&& predicate(ctx);
case "ContentType":
if (expression.EndsWith("*")) {
var prefix = expression.Substring(0, expression.Length - 1);
return ctx => ((ctx.ContentType ?? "").StartsWith(prefix) || (ctx.Stereotype ?? "").StartsWith(prefix)) && predicate(ctx);
}
return ctx => ((ctx.ContentType == expression) || (ctx.Stereotype == expression)) && predicate(ctx);
case "DisplayType":
if (expression.EndsWith("*")) {
var prefix = expression.Substring(0, expression.Length - 1);
return ctx => (ctx.DisplayType ?? "").StartsWith(prefix) && predicate(ctx);
}
return ctx => (ctx.DisplayType == expression) && predicate(ctx);
case "Path":
var normalizedPath = VirtualPathUtility.IsAbsolute(expression)
? VirtualPathUtility.ToAppRelative(expression)
: VirtualPathUtility.Combine("~/", expression);
private Func<ShapePlacementContext, bool> BuildPredicate(Func<ShapePlacementContext, bool> predicate,
KeyValuePair<string, string> term) {
return BuildPredicate(predicate, term, _placementParseMatchProviders);
}
if (normalizedPath.EndsWith("*")) {
var prefix = normalizedPath.Substring(0, normalizedPath.Length - 1);
return ctx => VirtualPathUtility.ToAppRelative(String.IsNullOrEmpty(ctx.Path) ? "/" : ctx.Path).StartsWith(prefix, StringComparison.OrdinalIgnoreCase) && predicate(ctx);
}
public static Func<ShapePlacementContext, bool> BuildPredicate(Func<ShapePlacementContext, bool> predicate,
KeyValuePair<string, string> term, IEnumerable<IPlacementParseMatchProvider> placementMatchProviders) {
normalizedPath = VirtualPathUtility.AppendTrailingSlash(normalizedPath);
return ctx => (ctx.Path.Equals(normalizedPath, StringComparison.OrdinalIgnoreCase)) && predicate(ctx);
if (placementMatchProviders != null) {
var providersForTerm = placementMatchProviders.Where(x => x.Key.Equals(term.Key));
if (providersForTerm.Any()) {
var expression = term.Value;
return ctx => providersForTerm.Any(x => x.Match(ctx, expression)) && predicate(ctx);
}
}
return predicate;
}

View File

@@ -176,6 +176,8 @@
<ItemGroup>
<Compile Include="ContentManagement\Extensions\DriverResultExtensions.cs" />
<Compile Include="ContentManagement\Handlers\CloneContentContext.cs" />
<Compile Include="DisplayManagement\Descriptors\ShapePlacementStrategy\DefaultPlacementParseMatchProviders.cs" />
<Compile Include="DisplayManagement\Descriptors\ShapePlacementStrategy\IPlacementParseMatchProvider.cs" />
<Compile Include="Environment\Configuration\ExtensionLocations.cs" />
<Compile Include="DisplayManagement\IPositioned.cs" />
<Compile Include="DisplayManagement\PositionWrapper.cs" />