diff --git a/src/Orchard.Web/Core/Common/Drivers/TextFieldDriver.cs b/src/Orchard.Web/Core/Common/Drivers/TextFieldDriver.cs index 5f10da91c..9292cc74a 100644 --- a/src/Orchard.Web/Core/Common/Drivers/TextFieldDriver.cs +++ b/src/Orchard.Web/Core/Common/Drivers/TextFieldDriver.cs @@ -16,12 +16,17 @@ namespace Orchard.Core.Common.Drivers { return part.PartDefinition.Name + "." + field.Name; } + private string GetDifferentiator(TextField field, ContentPart part) { + return field.Name; + } + protected override DriverResult Display(ContentPart part, TextField field, string displayType, dynamic shapeHelper) { - return ContentShape("Fields_Common_Text", () => shapeHelper.Fields_Common_Text(ContentField: field, Name: field.Name, Value: field.Value)); + return ContentShape("Fields_Common_Text", GetDifferentiator(field, part), + () => shapeHelper.Fields_Common_Text(ContentField: field, Name: field.Name, Value: field.Value)); } protected override DriverResult Editor(ContentPart part, TextField field, dynamic shapeHelper) { - return ContentShape("Fields_Common_Text_Edit", + return ContentShape("Fields_Common_Text_Edit", GetDifferentiator(field, part), () => shapeHelper.EditorTemplate(TemplateName: "Fields.Common.Text.Edit", Model: field, Prefix: GetPrefix(field, part))); } diff --git a/src/Orchard/ContentManagement/DefaultContentDisplay.cs b/src/Orchard/ContentManagement/DefaultContentDisplay.cs index 03634e2fd..44ee2fe89 100644 --- a/src/Orchard/ContentManagement/DefaultContentDisplay.cs +++ b/src/Orchard/ContentManagement/DefaultContentDisplay.cs @@ -95,19 +95,38 @@ namespace Orchard.ContentManagement { } private void BindPlacement(BuildShapeContext context, string displayType) { - context.FindPlacement = (partShapeType, defaultLocation) => { + context.FindPlacement = (partShapeType, differentiator, defaultLocation) => { //var workContext = _workContextAccessor.GetContext(); //var theme = workContext.CurrentTheme; var theme = _themeService.Value.GetRequestTheme(_requestContext); var shapeTable = _shapeTableManager.GetShapeTable(theme.Id); + ShapeDescriptor descriptor; if (shapeTable.Descriptors.TryGetValue(partShapeType, out descriptor)) { - var placementContext = new ShapePlacementContext { + ShapePlacementContext placementContext; + string location; + + // First, look up placement with differentiator + if (!string.IsNullOrEmpty(differentiator)) { + placementContext = new ShapePlacementContext { + ContentType = context.ContentItem.ContentType, + DisplayType = displayType, + Differentiator = differentiator, + }; + location = descriptor.Placement(placementContext); + if (!string.IsNullOrEmpty(location)) + return location; + } + + // Then fallback to placement without differentiator + placementContext = new ShapePlacementContext { ContentType = context.ContentItem.ContentType, - DisplayType = displayType + DisplayType = displayType, + Differentiator = null, }; - var location = descriptor.Placement(placementContext); - return location ?? defaultLocation; + location = descriptor.Placement(placementContext); + if (!string.IsNullOrEmpty(location)) + return location; } return defaultLocation; }; diff --git a/src/Orchard/ContentManagement/Drivers/ContentFieldDriver.cs b/src/Orchard/ContentManagement/Drivers/ContentFieldDriver.cs index 57a5d8fd4..8cc7fae4e 100644 --- a/src/Orchard/ContentManagement/Drivers/ContentFieldDriver.cs +++ b/src/Orchard/ContentManagement/Drivers/ContentFieldDriver.cs @@ -49,15 +49,23 @@ namespace Orchard.ContentManagement.Drivers { protected virtual DriverResult Editor(ContentPart part, TField field, IUpdateModel updater, dynamic shapeHelper) { return null; } public ContentShapeResult ContentShape(string shapeType, Func factory) { - return ContentShapeImplementation(shapeType, ctx => factory()); + return ContentShapeImplementation(shapeType, null, ctx => factory()); + } + + public ContentShapeResult ContentShape(string shapeType, string differentiator, Func factory) { + return ContentShapeImplementation(shapeType, differentiator, ctx => factory()); } public ContentShapeResult ContentShape(string shapeType, Func factory) { - return ContentShapeImplementation(shapeType, ctx=>factory(CreateShape(ctx, shapeType))); + return ContentShapeImplementation(shapeType, null, ctx => factory(CreateShape(ctx, shapeType))); } - private ContentShapeResult ContentShapeImplementation(string shapeType, Func shapeBuilder) { - return new ContentShapeResult(shapeType, Prefix, shapeBuilder); + public ContentShapeResult ContentShape(string shapeType, string differentiator, Func factory) { + return ContentShapeImplementation(shapeType, differentiator, ctx => factory(CreateShape(ctx, shapeType))); + } + + private ContentShapeResult ContentShapeImplementation(string shapeType, string differentiator, Func shapeBuilder) { + return new ContentShapeResult(shapeType, Prefix, shapeBuilder).Differentiator(differentiator); } private object CreateShape(BuildShapeContext context, string shapeType) { diff --git a/src/Orchard/ContentManagement/Drivers/ContentShapeResult.cs b/src/Orchard/ContentManagement/Drivers/ContentShapeResult.cs index be6451e12..1f902d072 100644 --- a/src/Orchard/ContentManagement/Drivers/ContentShapeResult.cs +++ b/src/Orchard/ContentManagement/Drivers/ContentShapeResult.cs @@ -5,6 +5,7 @@ using Orchard.DisplayManagement.Shapes; namespace Orchard.ContentManagement.Drivers { public class ContentShapeResult : DriverResult { private string _defaultLocation; + private string _differentiator; private readonly string _shapeType; private readonly string _prefix; private readonly Func _shapeBuilder; @@ -24,7 +25,7 @@ namespace Orchard.ContentManagement.Drivers { } private void ApplyImplementation(BuildShapeContext context, string displayType) { - var location = context.FindPlacement(_shapeType, _defaultLocation); + var location = context.FindPlacement(_shapeType, _differentiator, _defaultLocation); if (string.IsNullOrEmpty(location) || location == "-") return; @@ -49,5 +50,9 @@ namespace Orchard.ContentManagement.Drivers { _defaultLocation = zone; return this; } + public ContentShapeResult Differentiator(string differentiator) { + _differentiator = differentiator; + return this; + } } } \ No newline at end of file diff --git a/src/Orchard/ContentManagement/Handlers/BuildShapeContext.cs b/src/Orchard/ContentManagement/Handlers/BuildShapeContext.cs index 51728d6a3..15d890bfe 100644 --- a/src/Orchard/ContentManagement/Handlers/BuildShapeContext.cs +++ b/src/Orchard/ContentManagement/Handlers/BuildShapeContext.cs @@ -7,13 +7,13 @@ namespace Orchard.ContentManagement.Handlers { Shape = shape; ContentItem = content.ContentItem; New = shapeFactory; - FindPlacement = (partType, defaultLocation) => defaultLocation; + FindPlacement = (partType, differentiator, defaultLocation) => defaultLocation; } public dynamic Shape { get; private set; } public ContentItem ContentItem { get; private set; } public dynamic New { get; private set; } - public Func FindPlacement { get; set; } + public Func FindPlacement { get; set; } } } \ No newline at end of file diff --git a/src/Orchard/DisplayManagement/Descriptors/ShapeAlterationBuilder.cs b/src/Orchard/DisplayManagement/Descriptors/ShapeAlterationBuilder.cs index 93e796a46..5bb361e0f 100644 --- a/src/Orchard/DisplayManagement/Descriptors/ShapeAlterationBuilder.cs +++ b/src/Orchard/DisplayManagement/Descriptors/ShapeAlterationBuilder.cs @@ -110,6 +110,6 @@ namespace Orchard.DisplayManagement.Descriptors { public class ShapePlacementContext { public string ContentType { get; set; } public string DisplayType { get; set; } - + public string Differentiator { get; set; } } } diff --git a/src/Orchard/DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs b/src/Orchard/DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs index bf7c61f68..36708f0be 100644 --- a/src/Orchard/DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs +++ b/src/Orchard/DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs @@ -54,17 +54,31 @@ namespace Orchard.DisplayManagement.Descriptors.ShapePlacementStrategy { var shapeLocation = entry.Item1; var matches = entry.Item2; - Func predicate = ctx => true; + string shapeType; + string differentiator; + GetShapeType(shapeLocation, out shapeType, out differentiator); + + Func predicate = ctx => (ctx.Differentiator ?? "") == differentiator; if (matches.Any()) { predicate = matches.SelectMany(match => match.Terms).Aggregate(predicate, BuildPredicate); } - builder.Describe(shapeLocation.ShapeType) + builder.Describe(shapeType) .From(feature) .Placement(predicate, shapeLocation.Location); } } + private void GetShapeType(PlacementShapeLocation shapeLocation, out string shapeType, out string differentiator) { + differentiator = ""; + shapeType = shapeLocation.ShapeType; + var dashIndex = shapeType.LastIndexOf('-'); + if (dashIndex > 0 && dashIndex < shapeType.Length - 1) { + differentiator = shapeType.Substring(dashIndex + 1); + shapeType = shapeType.Substring(0, dashIndex); + } + } + private Func BuildPredicate(Func predicate, KeyValuePair term) { var expression = term.Value; switch (term.Key) {