mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Implemented import/export for *ElementWrapperPart*.
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
|
using System.Xml.Linq;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.Drivers;
|
using Orchard.ContentManagement.Drivers;
|
||||||
|
using Orchard.ContentManagement.Handlers;
|
||||||
using Orchard.Layouts.Framework.Display;
|
using Orchard.Layouts.Framework.Display;
|
||||||
using Orchard.Layouts.Framework.Drivers;
|
using Orchard.Layouts.Framework.Drivers;
|
||||||
using Orchard.Layouts.Framework.Elements;
|
using Orchard.Layouts.Framework.Elements;
|
||||||
@@ -14,10 +16,12 @@ namespace Orchard.Layouts.Drivers {
|
|||||||
public class ElementWrapperPartDriver : ContentPartDriver<ElementWrapperPart> {
|
public class ElementWrapperPartDriver : ContentPartDriver<ElementWrapperPart> {
|
||||||
private readonly IElementManager _elementManager;
|
private readonly IElementManager _elementManager;
|
||||||
private readonly IElementDisplay _elementDisplay;
|
private readonly IElementDisplay _elementDisplay;
|
||||||
|
private readonly IElementSerializer _serializer;
|
||||||
|
|
||||||
public ElementWrapperPartDriver(IElementManager elementManager, IElementDisplay elementDisplay) {
|
public ElementWrapperPartDriver(IElementManager elementManager, IElementDisplay elementDisplay, IElementSerializer serializer) {
|
||||||
_elementManager = elementManager;
|
_elementManager = elementManager;
|
||||||
_elementDisplay = elementDisplay;
|
_elementDisplay = elementDisplay;
|
||||||
|
_serializer = serializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override DriverResult Display(ElementWrapperPart part, string displayType, dynamic shapeHelper) {
|
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) {
|
private static DescribeElementsContext CreateDescribeContext(IContent part) {
|
||||||
return new DescribeElementsContext {
|
return new DescribeElementsContext {
|
||||||
Content = part
|
Content = part
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using Orchard.ContentManagement.MetaData;
|
||||||
using Orchard.ContentManagement.MetaData;
|
|
||||||
using Orchard.Core.Contents.Extensions;
|
using Orchard.Core.Contents.Extensions;
|
||||||
using Orchard.Data.Migration;
|
using Orchard.Data.Migration;
|
||||||
using Orchard.Layouts.Helpers;
|
using Orchard.Layouts.Helpers;
|
||||||
@@ -40,6 +39,7 @@ namespace Orchard.Layouts {
|
|||||||
.WithPart("CommonPart", p => p
|
.WithPart("CommonPart", p => p
|
||||||
.WithSetting("OwnerEditorSettings.ShowOwnerEditor", "false")
|
.WithSetting("OwnerEditorSettings.ShowOwnerEditor", "false")
|
||||||
.WithSetting("DateEditorSettings.ShowDateEditor", "false"))
|
.WithSetting("DateEditorSettings.ShowDateEditor", "false"))
|
||||||
|
.WithPart("IdentityPart")
|
||||||
.WithPart("WidgetPart")
|
.WithPart("WidgetPart")
|
||||||
.WithPart("LayoutPart")
|
.WithPart("LayoutPart")
|
||||||
.WithSetting("Stereotype", "Widget")
|
.WithSetting("Stereotype", "Widget")
|
||||||
@@ -76,6 +76,7 @@ namespace Orchard.Layouts {
|
|||||||
.WithSetting("OwnerEditorSettings.ShowOwnerEditor", "false")
|
.WithSetting("OwnerEditorSettings.ShowOwnerEditor", "false")
|
||||||
.WithSetting("DateEditorSettings.ShowDateEditor", "false"))
|
.WithSetting("DateEditorSettings.ShowDateEditor", "false"))
|
||||||
.WithPart("WidgetPart")
|
.WithPart("WidgetPart")
|
||||||
|
.WithPart("IdentityPart")
|
||||||
.WithPart("ElementWrapperPart", p => p
|
.WithPart("ElementWrapperPart", p => p
|
||||||
.WithSetting("ElementWrapperPartSettings.ElementTypeName", elementTypeName))
|
.WithSetting("ElementWrapperPartSettings.ElementTypeName", elementTypeName))
|
||||||
.WithSetting("Stereotype", "Widget")
|
.WithSetting("Stereotype", "Widget")
|
||||||
|
|||||||
@@ -461,9 +461,11 @@
|
|||||||
<Compile Include="Services\ILayoutEditorFactory.cs" />
|
<Compile Include="Services\ILayoutEditorFactory.cs" />
|
||||||
<Compile Include="Services\ILayoutModelMap.cs" />
|
<Compile Include="Services\ILayoutModelMap.cs" />
|
||||||
<Compile Include="Services\ILayoutModelMapper.cs" />
|
<Compile Include="Services\ILayoutModelMapper.cs" />
|
||||||
|
<Compile Include="Services\IElementSerializer.cs" />
|
||||||
<Compile Include="Services\IObjectStore.cs" />
|
<Compile Include="Services\IObjectStore.cs" />
|
||||||
<Compile Include="Services\LayoutEditorFactory.cs" />
|
<Compile Include="Services\LayoutEditorFactory.cs" />
|
||||||
<Compile Include="Services\LayoutModelMapper.cs" />
|
<Compile Include="Services\LayoutModelMapper.cs" />
|
||||||
|
<Compile Include="Services\ElementSerializer.cs" />
|
||||||
<Compile Include="Services\ObjectStore.cs" />
|
<Compile Include="Services\ObjectStore.cs" />
|
||||||
<Compile Include="Signals.cs" />
|
<Compile Include="Signals.cs" />
|
||||||
<Compile Include="Tokens\ElementTokens.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 System.Linq;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Orchard.Layouts.Elements;
|
|
||||||
using Orchard.Layouts.Framework.Elements;
|
using Orchard.Layouts.Framework.Elements;
|
||||||
using Orchard.Layouts.Helpers;
|
|
||||||
|
|
||||||
namespace Orchard.Layouts.Services {
|
namespace Orchard.Layouts.Services {
|
||||||
public class LayoutSerializer : ILayoutSerializer {
|
public class LayoutSerializer : ILayoutSerializer {
|
||||||
private readonly IElementManager _elementManager;
|
private readonly IElementSerializer _elementSerializer;
|
||||||
private readonly IElementFactory _elementFactory;
|
public LayoutSerializer(IElementSerializer elementSerializer) {
|
||||||
|
_elementSerializer = elementSerializer;
|
||||||
public LayoutSerializer(IElementManager elementManager, IElementFactory elementFactory) {
|
|
||||||
_elementManager = elementManager;
|
|
||||||
_elementFactory = elementFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Element> Deserialize(string data, DescribeElementsContext describeContext) {
|
public IEnumerable<Element> Deserialize(string data, DescribeElementsContext describeContext) {
|
||||||
@@ -26,7 +21,7 @@ namespace Orchard.Layouts.Services {
|
|||||||
var token = JToken.Parse(data);
|
var token = JToken.Parse(data);
|
||||||
var nodes = (JArray)token["elements"];
|
var nodes = (JArray)token["elements"];
|
||||||
var elements = nodes != null
|
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;
|
: emptyList;
|
||||||
|
|
||||||
return elements;
|
return elements;
|
||||||
@@ -34,66 +29,10 @@ namespace Orchard.Layouts.Services {
|
|||||||
|
|
||||||
public string Serialize(IEnumerable<Element> elements) {
|
public string Serialize(IEnumerable<Element> elements) {
|
||||||
var root = new {
|
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);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user