Implemented import/export for *ElementWrapperPart*.

This commit is contained in:
Sipke Schoorstra
2015-03-17 12:49:43 +01:00
parent 2d2f2b40dd
commit 5eb48b8eec
6 changed files with 144 additions and 69 deletions
@@ -1,7 +1,9 @@
using System.Linq;
using System.Web.Mvc;
using System.Xml.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.Handlers;
using Orchard.Layouts.Framework.Display;
using Orchard.Layouts.Framework.Drivers;
using Orchard.Layouts.Framework.Elements;
@@ -14,10 +16,12 @@ namespace Orchard.Layouts.Drivers {
public class ElementWrapperPartDriver : ContentPartDriver<ElementWrapperPart> {
private readonly IElementManager _elementManager;
private readonly IElementDisplay _elementDisplay;
private readonly IElementSerializer _serializer;
public ElementWrapperPartDriver(IElementManager elementManager, IElementDisplay elementDisplay) {
public ElementWrapperPartDriver(IElementManager elementManager, IElementDisplay elementDisplay, IElementSerializer serializer) {
_elementManager = elementManager;
_elementDisplay = elementDisplay;
_serializer = serializer;
}
protected override DriverResult Display(ElementWrapperPart part, string displayType, dynamic shapeHelper) {
@@ -63,6 +67,32 @@ namespace Orchard.Layouts.Drivers {
});
}
protected override void Exporting(ElementWrapperPart part, ExportContentContext context) {
var describeContext = CreateDescribeContext(part);
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, part.ElementTypeName);
var data = ElementDataHelper.Deserialize(part.ElementData);
var element = _elementManager.ActivateElement(descriptor, e => e.Data = data);
_elementManager.Exporting(new[] { element }, new ExportLayoutContext());
var exportableData = _serializer.Serialize(element);
context.Element(part.PartDefinition.Name).SetValue(exportableData);
}
protected override void Importing(ElementWrapperPart part, ImportContentContext context) {
var root = context.Data.Element(part.PartDefinition.Name);
if (root == null)
return;
var exportedData = root.Value;
var describeContext = CreateDescribeContext(part);
var element = _serializer.Deserialize(exportedData, describeContext);
_elementManager.Importing(new[]{element}, new ImportLayoutContext { Session = new ImportContentContextWrapper(context)});
part.ElementData = element.Data.Serialize();
}
private static DescribeElementsContext CreateDescribeContext(IContent part) {
return new DescribeElementsContext {
Content = part
@@ -1,5 +1,4 @@
using System;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData;
using Orchard.Core.Contents.Extensions;
using Orchard.Data.Migration;
using Orchard.Layouts.Helpers;
@@ -40,6 +39,7 @@ namespace Orchard.Layouts {
.WithPart("CommonPart", p => p
.WithSetting("OwnerEditorSettings.ShowOwnerEditor", "false")
.WithSetting("DateEditorSettings.ShowDateEditor", "false"))
.WithPart("IdentityPart")
.WithPart("WidgetPart")
.WithPart("LayoutPart")
.WithSetting("Stereotype", "Widget")
@@ -76,6 +76,7 @@ namespace Orchard.Layouts {
.WithSetting("OwnerEditorSettings.ShowOwnerEditor", "false")
.WithSetting("DateEditorSettings.ShowDateEditor", "false"))
.WithPart("WidgetPart")
.WithPart("IdentityPart")
.WithPart("ElementWrapperPart", p => p
.WithSetting("ElementWrapperPartSettings.ElementTypeName", elementTypeName))
.WithSetting("Stereotype", "Widget")
@@ -461,9 +461,11 @@
<Compile Include="Services\ILayoutEditorFactory.cs" />
<Compile Include="Services\ILayoutModelMap.cs" />
<Compile Include="Services\ILayoutModelMapper.cs" />
<Compile Include="Services\IElementSerializer.cs" />
<Compile Include="Services\IObjectStore.cs" />
<Compile Include="Services\LayoutEditorFactory.cs" />
<Compile Include="Services\LayoutModelMapper.cs" />
<Compile Include="Services\ElementSerializer.cs" />
<Compile Include="Services\ObjectStore.cs" />
<Compile Include="Signals.cs" />
<Compile Include="Tokens\ElementTokens.cs" />
@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Orchard.Layouts.Elements;
using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Helpers;
namespace Orchard.Layouts.Services {
public class ElementSerializer : IElementSerializer {
private readonly IElementManager _elementManager;
private readonly IElementFactory _elementFactory;
public ElementSerializer(IElementManager elementManager, IElementFactory elementFactory) {
_elementManager = elementManager;
_elementFactory = elementFactory;
}
public Element Deserialize(string data, DescribeElementsContext describeContext) {
if (String.IsNullOrWhiteSpace(data))
return null;
var token = JToken.Parse(data);
var element = ParseNode(node: token, parent: null, index: 0, describeContext: describeContext);
return element;
}
public string Serialize(Element element) {
var dto = ToDto(element);
return JToken.FromObject(dto).ToString(Formatting.None);
}
public object ToDto(Element element, int index = 0) {
var container = element as Container;
var dto = new {
typeName = element.Descriptor.TypeName,
data = element.Data.Serialize(),
exportableData = element.ExportableData.Serialize(),
index = index,
elements = container != null ? container.Elements.Select(ToDto).ToList() : new List<object>(),
isTemplated = element.IsTemplated,
htmlId = element.HtmlId,
htmlClass = element.HtmlClass,
htmlStyle = element.HtmlStyle
};
return dto;
}
public Element ParseNode(JToken node, Container parent, int index, DescribeElementsContext describeContext) {
var elementTypeName = (string)node["typeName"];
if (String.IsNullOrWhiteSpace(elementTypeName))
return null;
var data = (string) node["data"];
var htmlId = (string) node["htmlId"];
var htmlClass = (string)node["htmlClass"];
var htmlStyle = (string)node["htmlStyle"];
var elementData = ElementDataHelper.Deserialize(data);
var exportableData = ElementDataHelper.Deserialize((string)node["exportableData"]);
var childNodes = node["elements"];
var elementDescriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, elementTypeName);
if (elementDescriptor == null)
return null; // This happens if an element exists in a layout, but its type is no longer available due to its feature being disabled.
var element = _elementFactory.Activate(elementDescriptor, e => {
e.Container = parent;
e.Index = index;
e.Data = elementData;
e.ExportableData = exportableData;
e.HtmlId = htmlId;
e.HtmlClass = htmlClass;
e.HtmlStyle = htmlStyle;
});
var container = element as Container;
if (container != null)
container.Elements = childNodes != null
? childNodes.Select((x, i) => ParseNode(x, container, i, describeContext)).Where(x => x != null).ToList()
: new List<Element>();
element.IsTemplated = node.Value<bool>("isTemplated");
return element;
}
}
}
@@ -0,0 +1,12 @@
using Newtonsoft.Json.Linq;
using Orchard.Layouts.Elements;
using Orchard.Layouts.Framework.Elements;
namespace Orchard.Layouts.Services {
public interface IElementSerializer : IDependency {
Element Deserialize(string data, DescribeElementsContext describeContext);
string Serialize(Element element);
object ToDto(Element element, int index = 0);
Element ParseNode(JToken node, Container parent, int index, DescribeElementsContext describeContext);
}
}
@@ -3,18 +3,13 @@ using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Orchard.Layouts.Elements;
using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Helpers;
namespace Orchard.Layouts.Services {
public class LayoutSerializer : ILayoutSerializer {
private readonly IElementManager _elementManager;
private readonly IElementFactory _elementFactory;
public LayoutSerializer(IElementManager elementManager, IElementFactory elementFactory) {
_elementManager = elementManager;
_elementFactory = elementFactory;
private readonly IElementSerializer _elementSerializer;
public LayoutSerializer(IElementSerializer elementSerializer) {
_elementSerializer = elementSerializer;
}
public IEnumerable<Element> Deserialize(string data, DescribeElementsContext describeContext) {
@@ -26,7 +21,7 @@ namespace Orchard.Layouts.Services {
var token = JToken.Parse(data);
var nodes = (JArray)token["elements"];
var elements = nodes != null
? nodes.Select((x, i) => ParseNode(node: x, parent: null, index: i, describeContext: describeContext)).Where(x => x != null).ToArray()
? nodes.Select((x, i) => _elementSerializer.ParseNode(node: x, parent: null, index: i, describeContext: describeContext)).Where(x => x != null).ToArray()
: emptyList;
return elements;
@@ -34,66 +29,10 @@ namespace Orchard.Layouts.Services {
public string Serialize(IEnumerable<Element> elements) {
var root = new {
elements = elements.Select(Serialize).ToArray()
elements = elements.Select((x, i) => _elementSerializer.ToDto(x, i)).ToArray()
};
return JToken.FromObject(root).ToString(Formatting.None);
}
private static object Serialize(Element element, int index) {
var container = element as Container;
var dto = new {
typeName = element.Descriptor.TypeName,
data = element.Data.Serialize(),
exportableData = element.ExportableData.Serialize(),
index = index,
elements = container != null ? container.Elements.Select(Serialize).ToList() : new List<object>(),
isTemplated = element.IsTemplated,
htmlId = element.HtmlId,
htmlClass = element.HtmlClass,
htmlStyle = element.HtmlStyle
};
return dto;
}
private Element ParseNode(JToken node, Container parent, int index, DescribeElementsContext describeContext) {
var elementTypeName = (string)node["typeName"];
if (String.IsNullOrWhiteSpace(elementTypeName))
return null;
var data = (string) node["data"] ?? (string) node["state"]; // Falling back to "state" node for backwards compatibility.
var htmlId = (string) node["htmlId"];
var htmlClass = (string)node["htmlClass"];
var htmlStyle = (string)node["htmlStyle"];
var elementData = ElementDataHelper.Deserialize(data);
var exportableData = ElementDataHelper.Deserialize((string)node["exportableData"]);
var childNodes = node["elements"];
var elementDescriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, elementTypeName);
if (elementDescriptor == null)
return null; // This happens if an element exists in a layout, but its type is no longer available due to its feature being disabled.
var element = _elementFactory.Activate(elementDescriptor, e => {
e.Container = parent;
e.Index = index;
e.Data = elementData;
e.ExportableData = exportableData;
e.HtmlId = htmlId;
e.HtmlClass = htmlClass;
e.HtmlStyle = htmlStyle;
});
var container = element as Container;
if (container != null)
container.Elements = childNodes != null
? childNodes.Select((x, i) => ParseNode(x, container, i, describeContext)).Where(x => x != null).ToList()
: new List<Element>();
element.IsTemplated = node.Value<bool>("isTemplated");
return element;
}
}
}