diff --git a/src/Orchard.Tests/DisplayManagement/Descriptors/BasicShapeTemplateHarvesterTests.cs b/src/Orchard.Tests/DisplayManagement/Descriptors/BasicShapeTemplateHarvesterTests.cs index 4167c65d3..fc8b6770b 100644 --- a/src/Orchard.Tests/DisplayManagement/Descriptors/BasicShapeTemplateHarvesterTests.cs +++ b/src/Orchard.Tests/DisplayManagement/Descriptors/BasicShapeTemplateHarvesterTests.cs @@ -54,7 +54,6 @@ namespace Orchard.Tests.DisplayManagement.Descriptors { VerifyShapeType("Views/Items", "Content.Edit", "Items_Content_Edit"); } - [Test] public void ExplicitSpecializationMixedWithDisplayTypes() { VerifyShapeType("Views/Items", "Content-MyType", "Items_Content__MyType"); @@ -62,12 +61,18 @@ namespace Orchard.Tests.DisplayManagement.Descriptors { VerifyShapeType("Views/Items", "Content-MyType.Edit", "Items_Content_Edit__MyType"); } - [Test] public void ImplicitSpecializationMixedWithDisplayTypes() { VerifyShapeType("Views/Items", "MyType", "Items_Content__MyType"); VerifyShapeType("Views/Items", "MyType.Summary", "Items_Content_Summary__MyType"); VerifyShapeType("Views/Items", "MyType.Edit", "Items_Content_Edit__MyType"); } + + [Test] + public void MultipleDotsAreNormalizedToUnderscore() { + VerifyShapeType("Views/Parts", "Common.Body", "Parts_Common_Body"); + VerifyShapeType("Views/Parts", "Common.Body.Summary", "Parts_Common_Body_Summary"); + VerifyShapeType("Views/Parts", "Localization.ContentTranslations.Summary", "Parts_Localization_ContentTranslations_Summary"); + } } } diff --git a/src/Orchard.Web/Core/Common/Drivers/BodyPartDriver.cs b/src/Orchard.Web/Core/Common/Drivers/BodyPartDriver.cs index a9020d471..7c8d20e7f 100644 --- a/src/Orchard.Web/Core/Common/Drivers/BodyPartDriver.cs +++ b/src/Orchard.Web/Core/Common/Drivers/BodyPartDriver.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Web; using JetBrains.Annotations; @@ -36,33 +37,35 @@ namespace Orchard.Core.Common.Drivers { protected override DriverResult Display(BodyPart part, string displayType, dynamic shapeHelper) { return Combined( - ContentShape("Parts_Common_Body", displayType == "Detail" ? "Content" : null, () => { - var bodyText = _htmlFilters.Aggregate(part.Text, (text, filter) => filter.ProcessContent(text)); - return shapeHelper.Parts_Common_Body(ContentPart: part, Html: new HtmlString(bodyText)); - }), - ContentShape("Parts_Common_Body_Summary", displayType == "Summary" ? "Content" : null, () => { - var bodyText = _htmlFilters.Aggregate(part.Text, (text, filter) => filter.ProcessContent(text)); - return shapeHelper.Parts_Common_Body_Summary(ContentPart: part, Html: new HtmlString(bodyText)); - }) - ); + ContentShape("Parts_Common_Body", + () => { + var bodyText = _htmlFilters.Aggregate(part.Text, (text, filter) => filter.ProcessContent(text)); + return shapeHelper.Parts_Common_Body(ContentPart: part, Html: new HtmlString(bodyText)); + }), + ContentShape("Parts_Common_Body_Summary", + () => { + var bodyText = _htmlFilters.Aggregate(part.Text, (text, filter) => filter.ProcessContent(text)); + return shapeHelper.Parts_Common_Body_Summary(ContentPart: part, Html: new HtmlString(bodyText)); + }) + ); + } + + private string IfThen(bool predicate, string value) { + return predicate ? value : null; } protected override DriverResult Editor(BodyPart part, dynamic shapeHelper) { var model = BuildEditorViewModel(part); - var location = part.GetLocation("Editor"); - return ContentPartTemplate(model, TemplateName, Prefix).Location(location); + return ContentShape("Parts_Common_Body_Editor", + () => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix)); } protected override DriverResult Editor(BodyPart part, IUpdateModel updater, dynamic shapeHelper) { var model = BuildEditorViewModel(part); updater.TryUpdateModel(model, Prefix, null, null); - // only set the format if it has not yet been set to preserve the initial format type - might want to change this later to support changing body formats but...later - if (string.IsNullOrWhiteSpace(model.Format)) - model.Format = GetFlavor(part); - - var location = part.GetLocation("Editor"); - return ContentPartTemplate(model, TemplateName, Prefix).Location(location); + return ContentShape("Parts_Common_Body_Editor", + () => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix)); } private static BodyEditorViewModel BuildEditorViewModel(BodyPart part) { diff --git a/src/Orchard.Web/Core/Common/Placement.info b/src/Orchard.Web/Core/Common/Placement.info new file mode 100644 index 000000000..ce389cc31 --- /dev/null +++ b/src/Orchard.Web/Core/Common/Placement.info @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/src/Orchard.Web/Core/Common/Views/Parts/Common.Body.Summary.cshtml b/src/Orchard.Web/Core/Common/Views/Parts/Common.Body.Summary.cshtml index c01416962..374c67cfc 100644 --- a/src/Orchard.Web/Core/Common/Views/Parts/Common.Body.Summary.cshtml +++ b/src/Orchard.Web/Core/Common/Views/Parts/Common.Body.Summary.cshtml @@ -1,9 +1,9 @@ -@model BodyDisplayViewModel -@using Orchard.Core.Common.ViewModels; -@*doing excerpt generation on the way out for now so we don't stick ourselves with needing to regen excerpts for existing data +@*doing excerpt generation on the way out for now so we don't stick ourselves with needing to regen excerpts for existing data also, doing this here, inline, until we have a pluggable processing model (both in and out) also, ...this is ugly *@ @{ - var body = new HtmlString(Html.Excerpt(Model.Html.ToString(), 200).ToString().Replace(Environment.NewLine, "

" + Environment.NewLine + "

")); + Orchard.ContentManagement.ContentItem contentItem = Model.ContentPart.ContentItem; + string bodyHtml = Model.Html.ToString(); + var body = new HtmlString(Html.Excerpt(bodyHtml, 200).ToString().Replace(Environment.NewLine, "

" + Environment.NewLine + "

")); } -

@body @Html.ItemDisplayLink(T("[more]").ToString(), Model.BodyPart.ContentItem)

+

@body @Html.ItemDisplayLink(T("[more]").ToString(), contentItem)

diff --git a/src/Orchard.Web/Core/Contents/Shapes.cs b/src/Orchard.Web/Core/Contents/Shapes.cs index fddd989a0..b492501ea 100644 --- a/src/Orchard.Web/Core/Contents/Shapes.cs +++ b/src/Orchard.Web/Core/Contents/Shapes.cs @@ -8,7 +8,6 @@ namespace Orchard.Core.Contents { public class Shapes : IShapeTableProvider { public void Discover(ShapeTableBuilder builder) { builder.Describe("Items_Content") - .OnCreating(creating => creating.Behaviors.Add(new ZoneHoldingBehavior(name => ContentZone(creating, name)))) .OnDisplaying(displaying => { ContentItem contentItem = displaying.Shape.ContentItem; if (contentItem != null) { @@ -16,12 +15,14 @@ namespace Orchard.Core.Contents { displaying.ShapeMetadata.Alternates.Add("Items_Content__" + contentItem.Id); } }); - } - private static object ContentZone(ShapeCreatingContext creating, string name) { - var zone = creating.New.ContentZone(); - zone.ZoneName = name; - return zone; + builder.Describe("Items_Content_Editor") + .OnDisplaying(displaying => { + ContentItem contentItem = displaying.Shape.ContentItem; + if (contentItem != null) { + displaying.ShapeMetadata.Alternates.Add("Items_Content_Editor__" + contentItem.ContentType); + } + }); } } } diff --git a/src/Orchard.Web/Core/Contents/Views/Items/Content.Edit.cshtml b/src/Orchard.Web/Core/Contents/Views/Items/Content.Editor.cshtml similarity index 100% rename from src/Orchard.Web/Core/Contents/Views/Items/Content.Edit.cshtml rename to src/Orchard.Web/Core/Contents/Views/Items/Content.Editor.cshtml diff --git a/src/Orchard.Web/Core/Orchard.Core.csproj b/src/Orchard.Web/Core/Orchard.Core.csproj index 2beb761d3..ae26cebbb 100644 --- a/src/Orchard.Web/Core/Orchard.Core.csproj +++ b/src/Orchard.Web/Core/Orchard.Core.csproj @@ -381,7 +381,7 @@ - + @@ -392,6 +392,7 @@ + diff --git a/src/Orchard.Web/Core/Shapes/CoreShapes.cs b/src/Orchard.Web/Core/Shapes/CoreShapes.cs index fefbaec10..d31a001e2 100644 --- a/src/Orchard.Web/Core/Shapes/CoreShapes.cs +++ b/src/Orchard.Web/Core/Shapes/CoreShapes.cs @@ -31,7 +31,7 @@ namespace Orchard.Core.Shapes { // and has an automatic zone creating behavior builder.Describe("Layout") .Configure(descriptor => descriptor.Wrappers.Add("Document")) - .OnCreating(creating => creating.Behaviors.Add(new ZoneHoldingBehavior(name => CreateZone(creating)))) + .OnCreating(creating => creating.Behaviors.Add(new ZoneHoldingBehavior(() => creating.New.Zone()))) .OnCreated(created => { var layout = created.Shape; layout.Head = created.New.DocumentZone(ZoneName: "Head"); @@ -81,9 +81,6 @@ namespace Orchard.Core.Shapes { }); } - static object CreateZone(ShapeCreatingContext context) { - return context.New.Zone(); - } static TagBuilder GetTagBuilder(string tagName, string id, IEnumerable classes, IDictionary attributes) { var tagBuilder = new TagBuilder(tagName); @@ -271,8 +268,8 @@ namespace Orchard.Core.Shapes { } [Shape] - public void Partial(HtmlHelper Html, TextWriter Output, string TemplateName, object Model) { - RenderInternal(Html, Output, TemplateName, Model, null); + public void Partial(HtmlHelper Html, TextWriter Output, string TemplateName, object Model, string Prefix) { + RenderInternal(Html, Output, TemplateName, Model, Prefix); } [Shape] diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Drivers/TagsPartDriver.cs b/src/Orchard.Web/Modules/Orchard.Tags/Drivers/TagsPartDriver.cs index bfc32bfd3..2b63945e2 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Drivers/TagsPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.Tags/Drivers/TagsPartDriver.cs @@ -24,11 +24,8 @@ namespace Orchard.Tags.Drivers { public virtual IUser CurrentUser { get; set; } protected override DriverResult Display(TagsPart part, string displayType, dynamic shapeHelper) { - var showTags = shapeHelper.Parts_Tags_ShowTags(ContentPart: part, Tags: part.CurrentTags); - if (!string.IsNullOrWhiteSpace(displayType)) - showTags.Metadata.Type = string.Format("{0}.{1}", showTags.Metadata.Type, displayType); - var location = part.GetLocation(displayType); - return ContentShape(showTags).Location(location); + return ContentShape("Parts_Tags_ShowTags", + () => shapeHelper.Parts_Tags_ShowTags(ContentPart: part, Tags: part.CurrentTags)); } protected override DriverResult Editor(TagsPart part, dynamic shapeHelper) { diff --git a/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj b/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj index 5b2217ea1..819b7050b 100644 --- a/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj +++ b/src/Orchard.Web/Modules/Orchard.Tags/Orchard.Tags.csproj @@ -112,6 +112,9 @@ Orchard.Core + + + - - - diff --git a/src/Orchard/ContentManagement/DefaultContentDisplay.cs b/src/Orchard/ContentManagement/DefaultContentDisplay.cs index a90f29add..589fe36c2 100644 --- a/src/Orchard/ContentManagement/DefaultContentDisplay.cs +++ b/src/Orchard/ContentManagement/DefaultContentDisplay.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Routing; +using ClaySharp; +using ClaySharp.Implementation; using Microsoft.CSharp.RuntimeBinder; using Orchard.ContentManagement.Handlers; using Orchard.DisplayManagement; @@ -10,11 +12,13 @@ using Orchard.DisplayManagement.Descriptors; using Orchard.Logging; using Orchard.Mvc; using Orchard.Themes; +using Orchard.UI.Zones; namespace Orchard.ContentManagement { public class DefaultContentDisplay : IContentDisplay { private readonly Lazy> _handlers; private readonly IShapeHelperFactory _shapeHelperFactory; + private readonly IShapeFactory _shapeFactory; private readonly IShapeTableManager _shapeTableManager; private readonly IWorkContextAccessor _workContextAccessor; private readonly IHttpContextAccessor _httpContextAccessor; @@ -24,6 +28,7 @@ namespace Orchard.ContentManagement { public DefaultContentDisplay( Lazy> handlers, IShapeHelperFactory shapeHelperFactory, + IShapeFactory shapeFactory, IShapeTableManager shapeTableManager, IWorkContextAccessor workContextAccessor, IHttpContextAccessor httpContextAccessor, @@ -31,6 +36,7 @@ namespace Orchard.ContentManagement { RequestContext requestContext) { _handlers = handlers; _shapeHelperFactory = shapeHelperFactory; + _shapeFactory = shapeFactory; _shapeTableManager = shapeTableManager; _workContextAccessor = workContextAccessor; _httpContextAccessor = httpContextAccessor; @@ -55,29 +61,30 @@ namespace Orchard.ContentManagement { 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); + var actualShapeType = "Items_" + stereotype; + var actualDisplayType = string.IsNullOrWhiteSpace(displayType) ? "Detail" : displayType; + dynamic itemShape = CreateItemShape(actualShapeType); itemShape.ContentItem = content.ContentItem; - itemShape.Metadata.DisplayType = shapeDisplayType; + itemShape.Metadata.DisplayType = actualDisplayType; - var context = new BuildDisplayContext(itemShape, content, shapeDisplayType, _shapeHelperFactory); - BindPlacement(context, displayType); + var context = new BuildDisplayContext(itemShape, content, actualDisplayType, _shapeHelperFactory); + BindPlacement(context, actualDisplayType); _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(); + var contentTypeDefinition = content.ContentItem.TypeDefinition; + string stereotype; + if (!contentTypeDefinition.Settings.TryGetValue("Stereotype", out stereotype)) + stereotype = "Content"; - IContent iContent = content; - if (iContent != null) - itemShape.ContentItem = iContent.ContentItem; + var actualShapeType = "Items_" + stereotype + "_Editor"; + + dynamic itemShape = CreateItemShape(actualShapeType); + itemShape.ContentItem = content.ContentItem; var context = new BuildEditorContext(itemShape, content, _shapeHelperFactory); BindPlacement(context, null); @@ -87,12 +94,15 @@ namespace Orchard.ContentManagement { } public dynamic UpdateEditor(IContent content, IUpdateModel updater) { - var shapeHelper = _shapeHelperFactory.CreateHelper(); - var itemShape = shapeHelper.Items_Content_Edit(); + var contentTypeDefinition = content.ContentItem.TypeDefinition; + string stereotype; + if (!contentTypeDefinition.Settings.TryGetValue("Stereotype", out stereotype)) + stereotype = "Content"; - IContent iContent = content; - if (iContent != null) - itemShape.ContentItem = iContent.ContentItem; + var actualShapeType = "Items_" + stereotype + "_Editor"; + + dynamic itemShape = CreateItemShape(actualShapeType); + itemShape.ContentItem = content.ContentItem; var context = new UpdateEditorContext(itemShape, content, updater, _shapeHelperFactory); BindPlacement(context, null); @@ -101,6 +111,11 @@ namespace Orchard.ContentManagement { return context.Shape; } + private dynamic CreateItemShape(string actualShapeType) { + var zoneHoldingBehavior = new ZoneHoldingBehavior(() => _shapeFactory.Create("ContentZone", Arguments.Empty())); + return _shapeFactory.Create(actualShapeType, Arguments.Empty(), new[] { zoneHoldingBehavior }); + } + private void BindPlacement(BuildShapeContext context, string displayType) { context.FindPlacement = (partShapeType, defaultLocation) => { //var workContext = _workContextAccessor.GetContext(); @@ -109,9 +124,9 @@ namespace Orchard.ContentManagement { 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 placementContext = new ShapePlacementContext { + ContentType = context.ContentItem.ContentType, + DisplayType = displayType }; var location = descriptor.Placement(placementContext); return location ?? defaultLocation; diff --git a/src/Orchard/DisplayManagement/Descriptors/ShapeDescriptor.cs b/src/Orchard/DisplayManagement/Descriptors/ShapeDescriptor.cs index 1c7a64109..592b5b561 100644 --- a/src/Orchard/DisplayManagement/Descriptors/ShapeDescriptor.cs +++ b/src/Orchard/DisplayManagement/Descriptors/ShapeDescriptor.cs @@ -24,7 +24,8 @@ namespace Orchard.DisplayManagement.Descriptors { /// public string BindingSource { get { - return Bindings[ShapeType].BindingSource; + ShapeBinding binding; + return Bindings.TryGetValue(ShapeType, out binding) ? binding.BindingSource : null; } } diff --git a/src/Orchard/DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs b/src/Orchard/DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs index f77518c78..5461c6d6b 100644 --- a/src/Orchard/DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs +++ b/src/Orchard/DisplayManagement/Descriptors/ShapePlacementStrategy/ShapePlacementParsingStrategy.cs @@ -27,11 +27,11 @@ namespace Orchard.DisplayManagement.Descriptors.ShapePlacementStrategy { public void Discover(ShapeTableBuilder builder) { var availableFeatures = _extensionManager.AvailableFeatures(); - var activeFeatures = availableFeatures.Where(fd => FeatureIsTheme(fd) || FeatureIsEnabled(fd)); + var activeFeatures = availableFeatures.Where(fd => FeatureIsTheme(fd) || FeatureIsEnabled(fd)); var activeExtensions = Once(activeFeatures); foreach (var extensionDescriptor in activeExtensions) { - foreach (var featureDescriptor in extensionDescriptor.Features.Where(fd=>fd.Name == fd.Extension.Name)) { + foreach (var featureDescriptor in extensionDescriptor.Features.Where(fd => fd.Name == fd.Extension.Name)) { ProcessFeatureDescriptor(builder, featureDescriptor); } } @@ -46,7 +46,7 @@ namespace Orchard.DisplayManagement.Descriptors.ShapePlacementStrategy { } private void ProcessPlacementFile(ShapeTableBuilder builder, FeatureDescriptor featureDescriptor, PlacementFile placementFile) { - var feature = new Feature {Descriptor = featureDescriptor}; + var feature = new Feature { Descriptor = featureDescriptor }; // invert the tree into a list of leaves and the stack var entries = DrillDownShapeLocations(placementFile.Nodes, Enumerable.Empty()); @@ -55,7 +55,9 @@ namespace Orchard.DisplayManagement.Descriptors.ShapePlacementStrategy { var matches = entry.Item2; Func predicate = ctx => true; - predicate = matches.SelectMany(match=>match.Terms).Aggregate(predicate, BuildPredicate); + if (matches.Any()) { + predicate = matches.SelectMany(match => match.Terms).Aggregate(predicate, BuildPredicate); + } builder.Describe(shapeLocation.ShapeType) .From(feature) @@ -65,31 +67,39 @@ namespace Orchard.DisplayManagement.Descriptors.ShapePlacementStrategy { private Func BuildPredicate(Func predicate, KeyValuePair term) { var expression = term.Value; - switch(term.Key) { + switch (term.Key) { case "ContentType": - return ctx=>ctx.ContentType == expression ? true : predicate(ctx); + if (expression.EndsWith("*")) { + var prefix = expression.Substring(0, expression.Length - 1); + return ctx => (ctx.ContentType ?? "").StartsWith(prefix) && predicate(ctx); + } + return ctx => (ctx.ContentType == expression) && predicate(ctx); case "DisplayType": - return ctx=>ctx.DisplayType == expression ? true : predicate(ctx); + 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); } return predicate; } private static IEnumerable>> DrillDownShapeLocations( - IEnumerable nodes, + IEnumerable nodes, IEnumerable path) { - + // return shape locations nodes in this place foreach (var placementShapeLocation in nodes.OfType()) { yield return new Tuple>(placementShapeLocation, path); } // recurse down into match nodes foreach (var placementMatch in nodes.OfType()) { - foreach (var findShapeLocation in DrillDownShapeLocations(placementMatch.Nodes, path.Concat(new[] {placementMatch}))) { + foreach (var findShapeLocation in DrillDownShapeLocations(placementMatch.Nodes, path.Concat(new[] { placementMatch }))) { yield return findShapeLocation; } } - } + } private bool FeatureIsTheme(FeatureDescriptor fd) { return fd.Extension.ExtensionType == "Theme"; @@ -98,7 +108,7 @@ namespace Orchard.DisplayManagement.Descriptors.ShapePlacementStrategy { private bool FeatureIsEnabled(FeatureDescriptor fd) { return _shellDescriptor.Features.Any(sf => sf.Name == fd.Name); } - + private static IEnumerable Once(IEnumerable featureDescriptors) { var once = new ConcurrentDictionary(); return featureDescriptors.Select(fd => fd.Extension).Where(ed => once.TryAdd(ed.Name, null)).ToList(); diff --git a/src/Orchard/DisplayManagement/Descriptors/ShapeTemplateStrategy/IShapeTemplateHarvester.cs b/src/Orchard/DisplayManagement/Descriptors/ShapeTemplateStrategy/IShapeTemplateHarvester.cs index 5d3ab8e00..40e573555 100644 --- a/src/Orchard/DisplayManagement/Descriptors/ShapeTemplateStrategy/IShapeTemplateHarvester.cs +++ b/src/Orchard/DisplayManagement/Descriptors/ShapeTemplateStrategy/IShapeTemplateHarvester.cs @@ -26,7 +26,7 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy { } public IEnumerable HarvestShape(HarvestShapeInfo info) { - var lastDot = info.FileName.IndexOf('.'); + var lastDot = info.FileName.LastIndexOf('.'); if (lastDot <= 0) { yield return new HarvestShapeHit { ShapeType = Adjust(info.SubPath, info.FileName, null) diff --git a/src/Orchard/DisplayManagement/IShapeFactory.cs b/src/Orchard/DisplayManagement/IShapeFactory.cs index 3de5e3531..d0bd47aab 100644 --- a/src/Orchard/DisplayManagement/IShapeFactory.cs +++ b/src/Orchard/DisplayManagement/IShapeFactory.cs @@ -1,4 +1,5 @@ -using ClaySharp; +using System.Collections.Generic; +using ClaySharp; using ClaySharp.Implementation; namespace Orchard.DisplayManagement { @@ -8,6 +9,7 @@ namespace Orchard.DisplayManagement { /// public interface IShapeFactory : IDependency { IShape Create(string shapeType, INamedEnumerable parameters); + IShape Create(string shapeType, INamedEnumerable parameters, IEnumerable behaviors); } public static class ShapeFactoryExtensions { @@ -16,3 +18,4 @@ namespace Orchard.DisplayManagement { } } } + diff --git a/src/Orchard/DisplayManagement/Implementation/DefaultShapeFactory.cs b/src/Orchard/DisplayManagement/Implementation/DefaultShapeFactory.cs index 9f86dcef0..16432158e 100644 --- a/src/Orchard/DisplayManagement/Implementation/DefaultShapeFactory.cs +++ b/src/Orchard/DisplayManagement/Implementation/DefaultShapeFactory.cs @@ -16,8 +16,8 @@ namespace Orchard.DisplayManagement.Implementation { private readonly Lazy _shapeHelperFactory; public DefaultShapeFactory( - IEnumerable> events, - IShapeTableManager shapeTableManager, + IEnumerable> events, + IShapeTableManager shapeTableManager, Lazy shapeHelperFactory) { _events = events; _shapeTableManager = shapeTableManager; @@ -25,13 +25,17 @@ namespace Orchard.DisplayManagement.Implementation { } public IShape Create(string shapeType, INamedEnumerable parameters) { + return Create(shapeType, parameters, Enumerable.Empty()); + } + + public IShape Create(string shapeType, INamedEnumerable parameters, IEnumerable behaviors) { var defaultShapeTable = _shapeTableManager.GetShapeTable(null); - ShapeDescriptor shapeDescriptor; + ShapeDescriptor shapeDescriptor; defaultShapeTable.Descriptors.TryGetValue(shapeType, out shapeDescriptor); var creatingContext = new ShapeCreatingContext { New = _shapeHelperFactory.Value.CreateHelper(), - ShapeFactory=this, + ShapeFactory = this, ShapeType = shapeType, OnCreated = new List>() }; @@ -64,8 +68,13 @@ namespace Orchard.DisplayManagement.Implementation { new ClaySharp.Behaviors.NilResultBehavior() }; } + + if (behaviors != null && behaviors.Any()) { + // include behaviors passed in by caller, if any + creatingContext.Behaviors = creatingContext.Behaviors.Concat(behaviors).ToList(); + } - // "creating" events may add behaviors and alter base type + // "creating" events may add behaviors and alter base type) foreach (var ev in _events) { ev.Value.Creating(creatingContext); } @@ -102,7 +111,7 @@ namespace Orchard.DisplayManagement.Implementation { // other properties passed with call overlay any defaults, so are after the created events - + // only one non-Type, non-named argument is allowed var initializer = positional.SingleOrDefault(); if (initializer != null) { @@ -117,6 +126,8 @@ namespace Orchard.DisplayManagement.Implementation { return createdContext.Shape; } + + } diff --git a/src/Orchard/UI/Zones/ZoneHoldingBehavior.cs b/src/Orchard/UI/Zones/ZoneHoldingBehavior.cs index 50a563757..28bdb167c 100644 --- a/src/Orchard/UI/Zones/ZoneHoldingBehavior.cs +++ b/src/Orchard/UI/Zones/ZoneHoldingBehavior.cs @@ -20,9 +20,9 @@ namespace Orchard.UI.Zones { /// /// public class ZoneHoldingBehavior : ClayBehavior { - private readonly Func _zoneFactory; + private readonly Func _zoneFactory; - public ZoneHoldingBehavior(Func zoneFactory) { + public ZoneHoldingBehavior(Func zoneFactory) { _zoneFactory = zoneFactory; } @@ -50,10 +50,10 @@ namespace Orchard.UI.Zones { } public class ZonesBehavior : ClayBehavior { - private readonly Func _zoneFactory; + private readonly Func _zoneFactory; private readonly object _parent; - public ZonesBehavior(Func zoneFactory, object parent) { + public ZonesBehavior(Func zoneFactory, object parent) { _zoneFactory = zoneFactory; _parent = parent; } @@ -78,11 +78,11 @@ namespace Orchard.UI.Zones { } public class ZoneOnDemandBehavior : ClayBehavior { - private readonly Func _zoneFactory; + private readonly Func _zoneFactory; private readonly object _parent; private readonly string _potentialZoneName; - public ZoneOnDemandBehavior(Func zoneFactory, object parent, string potentialZoneName) { + public ZoneOnDemandBehavior(Func zoneFactory, object parent, string potentialZoneName) { _zoneFactory = zoneFactory; _parent = parent; _potentialZoneName = potentialZoneName; @@ -93,7 +93,7 @@ namespace Orchard.UI.Zones { if (name == "Add" && (argsCount == 1 || argsCount == 2)) { dynamic parent = _parent; - dynamic zone = _zoneFactory(_potentialZoneName); + dynamic zone = _zoneFactory(); zone.Parent = _parent; zone.ZoneName = _potentialZoneName; parent[_potentialZoneName] = zone;