Pushing driver and editor down to ElementDescriptor.

This allows for more granular control over what gets rendered when.
One scenario that this enables is where one can create an Element Blueprint and use it as a widget via the ElementWrapperPart.
This commit is contained in:
Sipke Schoorstra
2014-11-20 23:37:40 -08:00
parent 88d165e31c
commit e1ed30a1f8
10 changed files with 59 additions and 55 deletions

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.DisplayManagement; using Orchard.DisplayManagement;
using Orchard.Layouts.Framework.Drivers;
using Orchard.Layouts.Framework.Elements; using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Services; using Orchard.Layouts.Services;
using Orchard.UI.Zones; using Orchard.UI.Zones;
@@ -19,11 +20,11 @@ namespace Orchard.Layouts.Framework.Display {
} }
public dynamic DisplayElement( public dynamic DisplayElement(
IElement element, IElement element,
IContent content, IContent content,
string displayType = null, string displayType = null,
IUpdateModel updater = null, IUpdateModel updater = null,
string renderEventName = null, string renderEventName = null,
string renderEventArgs = null) { string renderEventArgs = null) {
var createShapeContext = new ElementCreatingDisplayShapeContext { var createShapeContext = new ElementCreatingDisplayShapeContext {
@@ -38,6 +39,8 @@ namespace Orchard.Layouts.Framework.Display {
var elementShape = (dynamic)_shapeFactory.Create("Element", elementShapeArguments, () => new ZoneHolding(() => _shapeFactory.Create("ElementZone"))); var elementShape = (dynamic)_shapeFactory.Create("Element", elementShapeArguments, () => new ZoneHolding(() => _shapeFactory.Create("ElementZone")));
var typeName = element.GetType().Name; var typeName = element.GetType().Name;
var category = element.Category.ToSafeName(); var category = element.Category.ToSafeName();
var drivers = element.Descriptor.GetDrivers();
elementShape.Metadata.DisplayType = displayType; elementShape.Metadata.DisplayType = displayType;
elementShape.Metadata.Alternates.Add(String.Format("Element_{0}", displayType)); elementShape.Metadata.Alternates.Add(String.Format("Element_{0}", displayType));
elementShape.Metadata.Alternates.Add(String.Format("Element__{0}", typeName)); elementShape.Metadata.Alternates.Add(String.Format("Element__{0}", typeName));
@@ -56,7 +59,8 @@ namespace Orchard.Layouts.Framework.Display {
}; };
_elementEventHandlerHandler.Displaying(displayContext); _elementEventHandlerHandler.Displaying(displayContext);
element.Descriptor.Displaying(displayContext); InvokeDrivers(drivers, driver => driver.Displaying(displayContext));
element.Descriptor.Display(displayContext);
var container = element as IContainer; var container = element as IContainer;
@@ -74,7 +78,7 @@ namespace Orchard.Layouts.Framework.Display {
} }
public dynamic DisplayElements(IEnumerable<IElement> elements, IContent content, string displayType = null, IUpdateModel updater = null, string renderEventName = null, string renderEventArgs = null) { public dynamic DisplayElements(IEnumerable<IElement> elements, IContent content, string displayType = null, IUpdateModel updater = null, string renderEventName = null, string renderEventArgs = null) {
var layoutRoot = (dynamic) _shapeFactory.Create("LayoutRoot"); var layoutRoot = (dynamic)_shapeFactory.Create("LayoutRoot");
foreach (var element in elements) { foreach (var element in elements) {
var elementShape = DisplayElement(element, content, displayType, updater, renderEventName, renderEventArgs); var elementShape = DisplayElement(element, content, displayType, updater, renderEventName, renderEventArgs);
@@ -104,5 +108,11 @@ namespace Orchard.Layouts.Framework.Display {
private static string MakeValidName(string key) { private static string MakeValidName(string key) {
return key.Replace(".", "_"); return key.Replace(".", "_");
} }
private void InvokeDrivers(IEnumerable<IElementDriver> drivers, Action<IElementDriver> driverAction) {
foreach (var driver in drivers) {
driverAction(driver);
}
}
} }
} }

View File

@@ -1,6 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Orchard.Layouts.Framework.Display; using Orchard.Layouts.Framework.Display;
using Orchard.Layouts.Framework.Drivers;
using Orchard.Localization; using Orchard.Localization;
namespace Orchard.Layouts.Framework.Elements { namespace Orchard.Layouts.Framework.Elements {
@@ -10,8 +12,11 @@ namespace Orchard.Layouts.Framework.Elements {
TypeName = typeName; TypeName = typeName;
DisplayText = displayText; DisplayText = displayText;
Category = category; Category = category;
CreatingDisplay = context => {}; GetDrivers = Enumerable.Empty<IElementDriver>;
Displaying = context => {}; CreatingDisplay = context => { };
Display = context => {};
Editor = context => { };
UpdateEditor = context => { };
StateBag = new Dictionary<string, object>(); StateBag = new Dictionary<string, object>();
} }
@@ -19,8 +24,11 @@ namespace Orchard.Layouts.Framework.Elements {
public string Category { get; set; } public string Category { get; set; }
public Type ElementType { get; set; } public Type ElementType { get; set; }
public string TypeName { get; set; } public string TypeName { get; set; }
public Func<IEnumerable<IElementDriver>> GetDrivers { get; set; }
public Action<ElementCreatingDisplayShapeContext> CreatingDisplay { get; set; } public Action<ElementCreatingDisplayShapeContext> CreatingDisplay { get; set; }
public Action<ElementDisplayContext> Displaying { get; set; } public Action<ElementDisplayContext> Display { get; set; }
public Action<ElementEditorContext> Editor { get; set; }
public Action<ElementEditorContext> UpdateEditor { get; set; }
public bool IsSystemElement { get; set; } public bool IsSystemElement { get; set; }
public bool EnableEditorDialog { get; set; } public bool EnableEditorDialog { get; set; }
public IDictionary<string, object> StateBag { get; set; } public IDictionary<string, object> StateBag { get; set; }

View File

@@ -1,33 +0,0 @@
using Orchard.Layouts.Framework.Drivers;
using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Helpers;
using Orchard.Layouts.Services;
using Orchard.Layouts.Settings;
namespace Orchard.Layouts.Handlers {
public class ElementSettingsHandler : ElementEventHandlerBase {
public override void BuildEditor(ElementEditorContext context) {
var viewModel = context.Element.State.GetModel<CommonElementSettings>();
var commonSettingsEditor = context.ShapeFactory.EditorTemplate(
TemplateName: "ElementSettings.Common",
Model: viewModel,
Prefix: "CommonElementSettings");
commonSettingsEditor.Metadata.Position = "Settings:5";
context.EditorResult.Add(commonSettingsEditor);
if (context.Updater != null) {
context.Updater.TryUpdateModel(viewModel, context.Prefix.AppendPrefix("CommonElementSettings"), null, null);
context.Element.State = context.Element.State.Combine(new StateDictionary {
{"CommonElementSettings.Id", viewModel.Id},
{"CommonElementSettings.CssClass", viewModel.CssClass},
{"CommonElementSettings.InlineStyle", viewModel.InlineStyle}
});
}
}
public override void UpdateEditor(ElementEditorContext context) {
BuildEditor(context);
}
}
}

View File

@@ -260,7 +260,6 @@
<Compile Include="Drivers\MarkdownDriver.cs" /> <Compile Include="Drivers\MarkdownDriver.cs" />
<Compile Include="Elements\ContentField.cs" /> <Compile Include="Elements\ContentField.cs" />
<Compile Include="Elements\ContentItem.cs" /> <Compile Include="Elements\ContentItem.cs" />
<Compile Include="Handlers\ElementSettingsHandler.cs" />
<Compile Include="Elements\Html.cs" /> <Compile Include="Elements\Html.cs" />
<Compile Include="Elements\Markdown.cs" /> <Compile Include="Elements\Markdown.cs" />
<Compile Include="Framework\Elements\StateDictionary.cs" /> <Compile Include="Framework\Elements\StateDictionary.cs" />

View File

@@ -40,7 +40,7 @@ namespace Orchard.Layouts.Providers {
EnableEditorDialog = false, EnableEditorDialog = false,
IsSystemElement = false, IsSystemElement = false,
CreatingDisplay = creatingDisplayContext => CreatingDisplay(creatingDisplayContext, blueprint), CreatingDisplay = creatingDisplayContext => CreatingDisplay(creatingDisplayContext, blueprint),
Displaying = displayContext => Displaying(displayContext, baseElement), Display = displayContext => Displaying(displayContext, baseElement),
StateBag = new Dictionary<string, object> { StateBag = new Dictionary<string, object> {
{"ElementTypeName", baseElement.Descriptor.TypeName} {"ElementTypeName", baseElement.Descriptor.TypeName}
} }
@@ -56,7 +56,9 @@ namespace Orchard.Layouts.Providers {
} }
private void CreatingDisplay(ElementCreatingDisplayShapeContext context, ElementBlueprint blueprint) { private void CreatingDisplay(ElementCreatingDisplayShapeContext context, ElementBlueprint blueprint) {
context.Element.State = ElementStateHelper.Deserialize(blueprint.BaseElementState); var bluePrintState = ElementStateHelper.Deserialize(blueprint.BaseElementState);
var elementState = context.Element.State.Where(x => !String.IsNullOrWhiteSpace(x.Value)).ToDictionary(x => x.Key, x => x.Value);
context.Element.State = bluePrintState.Combine(new StateDictionary(elementState));
} }
private void Displaying(ElementDisplayContext context, IElement element) { private void Displaying(ElementDisplayContext context, IElement element) {

View File

@@ -45,7 +45,7 @@ namespace Orchard.Layouts.Providers {
var name = String.Format("{0}.{1}", part.Name, field.Name); var name = String.Format("{0}.{1}", part.Name, field.Name);
var displayName = field.DisplayName; var displayName = field.DisplayName;
yield return new ElementDescriptor(elementType, name, T(displayName), contentFieldElement.Category) { yield return new ElementDescriptor(elementType, name, T(displayName), contentFieldElement.Category) {
Displaying = displayContext => Displaying(displayContext), Display = displayContext => Displaying(displayContext),
}; };
} }
} }

View File

@@ -31,7 +31,7 @@ namespace Orchard.Layouts.Providers {
var contentParts = GetContentParts(context); var contentParts = GetContentParts(context);
return contentParts.Select(contentPart => new ElementDescriptor(elementType, contentPart.Name, T(contentPart.Name), contentPartElement.Category) { return contentParts.Select(contentPart => new ElementDescriptor(elementType, contentPart.Name, T(contentPart.Name), contentPartElement.Category) {
Displaying = displayContext => Displaying(displayContext), Display = displayContext => Displaying(displayContext),
StateBag = new Dictionary<string, object> { StateBag = new Dictionary<string, object> {
{"ElementTypeName", contentPart.Name} {"ElementTypeName", contentPart.Name}
} }

View File

@@ -49,7 +49,7 @@ namespace Orchard.Layouts.Providers {
var elementName = GetDisplayName(shapeDescriptor.Value.BindingSource); var elementName = GetDisplayName(shapeDescriptor.Value.BindingSource);
var closureDescriptor = shapeDescriptor; var closureDescriptor = shapeDescriptor;
yield return new ElementDescriptor(elementType, shapeType, T(elementName), snippetElement.Category) { yield return new ElementDescriptor(elementType, shapeType, T(elementName), snippetElement.Category) {
Displaying = displayContext => Displaying(displayContext, closureDescriptor.Value) Display = displayContext => Displaying(displayContext, closureDescriptor.Value)
}; };
} }
} }

View File

@@ -1,10 +1,12 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Orchard.Environment; using Orchard.Environment;
using Orchard.Layouts.Framework.Display; using Orchard.Layouts.Framework.Drivers;
using Orchard.Layouts.Framework.Elements; using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Framework.Harvesters; using Orchard.Layouts.Framework.Harvesters;
using Orchard.Layouts.Helpers;
using Orchard.Layouts.Services; using Orchard.Layouts.Services;
using Orchard.Layouts.Settings;
namespace Orchard.Layouts.Providers { namespace Orchard.Layouts.Providers {
public class TypedElementHarvester : IElementHarvester { public class TypedElementHarvester : IElementHarvester {
@@ -22,18 +24,32 @@ namespace Orchard.Layouts.Providers {
return elementTypes.Select(elementType => { return elementTypes.Select(elementType => {
var element = _factory.Value.Activate(elementType); var element = _factory.Value.Activate(elementType);
return new ElementDescriptor(elementType, element.Type, element.DisplayText, element.Category) { return new ElementDescriptor(elementType, element.Type, element.DisplayText, element.Category) {
Displaying = displayContext => Displaying(displayContext, element), GetDrivers = () => _elementManager.Value.GetDrivers(element),
Editor = Editor,
UpdateEditor = Editor,
IsSystemElement = element.IsSystemElement, IsSystemElement = element.IsSystemElement,
EnableEditorDialog = element.HasEditor EnableEditorDialog = element.HasEditor
}; };
}); });
} }
private void Displaying(ElementDisplayContext context, IElement element) { private void Editor(ElementEditorContext context) {
var drivers = _elementManager.Value.GetDrivers(element); var viewModel = context.Element.State.GetModel<CommonElementSettings>();
var commonSettingsEditor = context.ShapeFactory.EditorTemplate(
TemplateName: "ElementSettings.Common",
Model: viewModel,
Prefix: "CommonElementSettings");
foreach (var driver in drivers) { commonSettingsEditor.Metadata.Position = "Settings:5";
driver.Displaying(context); context.EditorResult.Add(commonSettingsEditor);
if (context.Updater != null) {
context.Updater.TryUpdateModel(viewModel, context.Prefix.AppendPrefix("CommonElementSettings"), null, null);
context.Element.State = context.Element.State.Combine(new StateDictionary {
{"CommonElementSettings.Id", viewModel.Id},
{"CommonElementSettings.CssClass", viewModel.CssClass},
{"CommonElementSettings.InlineStyle", viewModel.InlineStyle}
});
} }
} }
} }

View File

@@ -110,7 +110,7 @@ namespace Orchard.Layouts.Services {
} }
public IEnumerable<IElementDriver> GetDrivers(ElementDescriptor descriptor) { public IEnumerable<IElementDriver> GetDrivers(ElementDescriptor descriptor) {
return GetDrivers(descriptor.ElementType); return descriptor.GetDrivers();
} }
public IEnumerable<IElementDriver> GetDrivers(IElement element) { public IEnumerable<IElementDriver> GetDrivers(IElement element) {
@@ -128,11 +128,13 @@ namespace Orchard.Layouts.Services {
public EditorResult BuildEditor(ElementEditorContext context) { public EditorResult BuildEditor(ElementEditorContext context) {
_elementEventHandler.BuildEditor(context); _elementEventHandler.BuildEditor(context);
context.Element.Descriptor.Editor(context);
return context.EditorResult; return context.EditorResult;
} }
public EditorResult UpdateEditor(ElementEditorContext context) { public EditorResult UpdateEditor(ElementEditorContext context) {
_elementEventHandler.UpdateEditor(context); _elementEventHandler.UpdateEditor(context);
context.Element.Descriptor.UpdateEditor(context);
return context.EditorResult; return context.EditorResult;
} }