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 Orchard.ContentManagement;
using Orchard.DisplayManagement;
using Orchard.Layouts.Framework.Drivers;
using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Services;
using Orchard.UI.Zones;
@@ -19,11 +20,11 @@ namespace Orchard.Layouts.Framework.Display {
}
public dynamic DisplayElement(
IElement element,
IContent content,
string displayType = null,
IElement element,
IContent content,
string displayType = null,
IUpdateModel updater = null,
string renderEventName = null,
string renderEventName = null,
string renderEventArgs = null) {
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 typeName = element.GetType().Name;
var category = element.Category.ToSafeName();
var drivers = element.Descriptor.GetDrivers();
elementShape.Metadata.DisplayType = displayType;
elementShape.Metadata.Alternates.Add(String.Format("Element_{0}", displayType));
elementShape.Metadata.Alternates.Add(String.Format("Element__{0}", typeName));
@@ -56,7 +59,8 @@ namespace Orchard.Layouts.Framework.Display {
};
_elementEventHandlerHandler.Displaying(displayContext);
element.Descriptor.Displaying(displayContext);
InvokeDrivers(drivers, driver => driver.Displaying(displayContext));
element.Descriptor.Display(displayContext);
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) {
var layoutRoot = (dynamic) _shapeFactory.Create("LayoutRoot");
var layoutRoot = (dynamic)_shapeFactory.Create("LayoutRoot");
foreach (var element in elements) {
var elementShape = DisplayElement(element, content, displayType, updater, renderEventName, renderEventArgs);
@@ -104,5 +108,11 @@ namespace Orchard.Layouts.Framework.Display {
private static string MakeValidName(string key) {
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.Collections.Generic;
using System.Linq;
using Orchard.Layouts.Framework.Display;
using Orchard.Layouts.Framework.Drivers;
using Orchard.Localization;
namespace Orchard.Layouts.Framework.Elements {
@@ -10,8 +12,11 @@ namespace Orchard.Layouts.Framework.Elements {
TypeName = typeName;
DisplayText = displayText;
Category = category;
CreatingDisplay = context => {};
Displaying = context => {};
GetDrivers = Enumerable.Empty<IElementDriver>;
CreatingDisplay = context => { };
Display = context => {};
Editor = context => { };
UpdateEditor = context => { };
StateBag = new Dictionary<string, object>();
}
@@ -19,8 +24,11 @@ namespace Orchard.Layouts.Framework.Elements {
public string Category { get; set; }
public Type ElementType { get; set; }
public string TypeName { get; set; }
public Func<IEnumerable<IElementDriver>> GetDrivers { 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 EnableEditorDialog { 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="Elements\ContentField.cs" />
<Compile Include="Elements\ContentItem.cs" />
<Compile Include="Handlers\ElementSettingsHandler.cs" />
<Compile Include="Elements\Html.cs" />
<Compile Include="Elements\Markdown.cs" />
<Compile Include="Framework\Elements\StateDictionary.cs" />

View File

@@ -40,7 +40,7 @@ namespace Orchard.Layouts.Providers {
EnableEditorDialog = false,
IsSystemElement = false,
CreatingDisplay = creatingDisplayContext => CreatingDisplay(creatingDisplayContext, blueprint),
Displaying = displayContext => Displaying(displayContext, baseElement),
Display = displayContext => Displaying(displayContext, baseElement),
StateBag = new Dictionary<string, object> {
{"ElementTypeName", baseElement.Descriptor.TypeName}
}
@@ -56,7 +56,9 @@ namespace Orchard.Layouts.Providers {
}
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) {

View File

@@ -45,7 +45,7 @@ namespace Orchard.Layouts.Providers {
var name = String.Format("{0}.{1}", part.Name, field.Name);
var displayName = field.DisplayName;
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);
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> {
{"ElementTypeName", contentPart.Name}
}

View File

@@ -49,7 +49,7 @@ namespace Orchard.Layouts.Providers {
var elementName = GetDisplayName(shapeDescriptor.Value.BindingSource);
var closureDescriptor = shapeDescriptor;
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.Linq;
using Orchard.Environment;
using Orchard.Layouts.Framework.Display;
using Orchard.Layouts.Framework.Drivers;
using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Framework.Harvesters;
using Orchard.Layouts.Helpers;
using Orchard.Layouts.Services;
using Orchard.Layouts.Settings;
namespace Orchard.Layouts.Providers {
public class TypedElementHarvester : IElementHarvester {
@@ -22,18 +24,32 @@ namespace Orchard.Layouts.Providers {
return elementTypes.Select(elementType => {
var element = _factory.Value.Activate(elementType);
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,
EnableEditorDialog = element.HasEditor
};
});
}
private void Displaying(ElementDisplayContext context, IElement element) {
var drivers = _elementManager.Value.GetDrivers(element);
private void Editor(ElementEditorContext context) {
var viewModel = context.Element.State.GetModel<CommonElementSettings>();
var commonSettingsEditor = context.ShapeFactory.EditorTemplate(
TemplateName: "ElementSettings.Common",
Model: viewModel,
Prefix: "CommonElementSettings");
foreach (var driver in drivers) {
driver.Displaying(context);
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}
});
}
}
}

View File

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