Orchard.Layouts: Restoring backwards-compatibility with Snippets that don't have a separate manifest

This commit is contained in:
Lombiq 2018-12-18 15:07:04 +01:00
parent c91bd63fca
commit efcf028696
2 changed files with 44 additions and 56 deletions

View File

@ -7,9 +7,9 @@ using Orchard.Localization;
namespace Orchard.Layouts.Helpers { namespace Orchard.Layouts.Helpers {
public static class SnippetHtmlExtensions { public static class SnippetHtmlExtensions {
public static SnippetFieldDescriptorBuilder SnippetField(this HtmlHelper htmlHelper, string name, string type = null) { public static SnippetFieldDescriptorBuilder SnippetField(this HtmlHelper htmlHelper, string name, string type = null) {
var shape = (dynamic) htmlHelper.ViewData.Model; var shape = (dynamic)htmlHelper.ViewData.Model;
return new SnippetFieldDescriptorBuilder(shape) return new SnippetFieldDescriptorBuilder(shape)
.Named(name) .Named(name)
@ -47,17 +47,11 @@ namespace Orchard.Layouts.Helpers {
} }
public override string ToString() { public override string ToString() {
var registratorCallback = (Action<SnippetFieldDescriptor>)_shape.DescriptorRegistrationCallback; ((Action<SnippetFieldDescriptor>)_shape.DescriptorRegistrationCallback)?.Invoke(Descriptor);
if (registratorCallback != null)
registratorCallback(Descriptor);
var element = (Snippet)_shape.Element; var element = (Snippet)_shape.Element;
if(element != null) return element?.Data.Get(Descriptor.Name);
return element.Data.Get(Descriptor.Name);
return null;
} }
public string ToHtmlString() { public string ToHtmlString() {

View File

@ -73,23 +73,19 @@ namespace Orchard.Layouts.Providers {
var snippetElement = (Snippet)_elementFactory.Value.Activate(elementType); var snippetElement = (Snippet)_elementFactory.Value.Activate(elementType);
foreach (var shapeDescriptor in shapeDescriptors) { foreach (var shapeDescriptor in shapeDescriptors) {
var snippetDescriptor = ParseSnippetManifest(shapeDescriptor.Value, snippetElement); var snippetDescriptor = CreateSnippetDescriptor(shapeDescriptor.Value, snippetElement);
if (snippetDescriptor == null) continue;
var shapeType = shapeDescriptor.Value.ShapeType; var shapeType = shapeDescriptor.Value.ShapeType;
yield return new ElementDescriptor(elementType, shapeType, snippetDescriptor.DisplayName, snippetDescriptor.Description, snippetDescriptor.Category) { yield return new ElementDescriptor(elementType, shapeType, snippetDescriptor.DisplayName, snippetDescriptor.Description, snippetDescriptor.Category) {
Displaying = displayContext => Displaying(displayContext, shapeDescriptor.Value, snippetDescriptor), Displaying = displayContext => Displaying(displayContext, shapeDescriptor.Value, snippetDescriptor),
ToolboxIcon = snippetDescriptor.ToolboxIcon, ToolboxIcon = snippetDescriptor.ToolboxIcon,
EnableEditorDialog = snippetDescriptor.Fields.Any(), EnableEditorDialog = snippetDescriptor.Fields.Any(),
Editor = ctx => Editor(snippetDescriptor ?? DescribeSnippet(shapeType, snippetElement), ctx), Editor = ctx => Editor(snippetDescriptor, ctx),
UpdateEditor = ctx => UpdateEditor(snippetDescriptor ?? DescribeSnippet(shapeType, snippetElement), ctx) UpdateEditor = ctx => UpdateEditor(snippetDescriptor, ctx)
}; };
} }
} }
private void Editor(SnippetDescriptor descriptor, ElementEditorContext context) { private void Editor(SnippetDescriptor descriptor, ElementEditorContext context) {
UpdateEditor(descriptor, context); UpdateEditor(descriptor, context);
} }
@ -146,31 +142,57 @@ namespace Orchard.Layouts.Providers {
context.ElementShape.Snippet = shape; context.ElementShape.Snippet = shape;
} }
private SnippetDescriptor ParseSnippetManifest(ShapeDescriptor shape, Snippet snippetElement) { private SnippetDescriptor CreateSnippetDescriptor(ShapeDescriptor shapeDescriptor, Snippet snippetElement) {
// Initializing and checking access to the Snippet manifest file. // Initializing and checking access to the Snippet manifest file.
var physicalSourcePath = _wca.GetContext().HttpContext.Server.MapPath(shape.BindingSource); var physicalSourcePath = _wca.GetContext().HttpContext.Server.MapPath(shapeDescriptor.BindingSource);
var fullPath = Path.Combine( var fullPath = Path.Combine(
Path.GetDirectoryName(physicalSourcePath) ?? "", Path.GetDirectoryName(physicalSourcePath) ?? "",
Path.GetFileNameWithoutExtension(physicalSourcePath) + ".txt"); Path.GetFileNameWithoutExtension(physicalSourcePath) + ".txt");
if (!File.Exists(fullPath)) return null; SnippetDescriptor descriptor;
// Reading and parsing the manifest if it exists.
if (File.Exists(fullPath)) {
var deserializer = new DeserializerBuilder()
.IgnoreUnmatchedProperties()
.WithTypeConverter(new LocalizedStringYamlConverter())
.Build();
// Reading and parsing the manifest. descriptor = deserializer.Deserialize<SnippetDescriptor>(File.OpenText(fullPath));
var deserializer = new DeserializerBuilder() }
.IgnoreUnmatchedProperties() // Otherwise extract the Fields from the Snippet shape template.
.WithTypeConverter(new LocalizedStringYamlConverter()) else {
.Build(); var shape = (dynamic)_shapeFactory.Value.Create(shapeDescriptor.ShapeType);
var descriptor = deserializer.Deserialize<SnippetDescriptor>(File.OpenText(fullPath)); shape.Element = snippetElement;
descriptor = new SnippetDescriptor();
shape.DescriptorRegistrationCallback = (Action<SnippetFieldDescriptor>)(fieldDescriptor => {
// Not using Dictionary, as that will break rendering the view for some obscure reason.
var existingFieldDescriptor = descriptor.Fields.SingleOrDefault(field => field.Name == fieldDescriptor.Name);
if (existingFieldDescriptor == null)
descriptor.Fields.Add(fieldDescriptor);
if (fieldDescriptor.DisplayName == null)
fieldDescriptor.DisplayName = new LocalizedString(fieldDescriptor.Name);
});
using (_currentThemeShapeBindingResolver.Value.Enable()) {
_shapeDisplay.Value.Display(shape);
}
shape.SnippetDescriptor = descriptor;
}
// Checking the validity of the parsed values, include those of the Snippet's Fields. // Checking the validity of the parsed values, include those of the Snippet's Fields.
if (string.IsNullOrEmpty(descriptor.Category)) if (string.IsNullOrEmpty(descriptor.Category))
descriptor.Category = snippetElement.Category; descriptor.Category = snippetElement.Category;
if (string.IsNullOrEmpty(descriptor.Description?.Text)) if (string.IsNullOrEmpty(descriptor.Description?.Text))
descriptor.Description = T("An element that renders the {0} shape.", shape.ShapeType); descriptor.Description = T("An element that renders the {0} shape.", shapeDescriptor.ShapeType);
if (string.IsNullOrEmpty(descriptor.DisplayName?.Text)) { if (string.IsNullOrEmpty(descriptor.DisplayName?.Text)) {
var fileName = Path.GetFileNameWithoutExtension(shape.BindingSource) ?? ""; var fileName = Path.GetFileNameWithoutExtension(shapeDescriptor.BindingSource) ?? "";
var lastIndex = fileName.IndexOf(SnippetShapeSuffix, StringComparison.OrdinalIgnoreCase); var lastIndex = fileName.IndexOf(SnippetShapeSuffix, StringComparison.OrdinalIgnoreCase);
descriptor.DisplayName = T(fileName.Substring(0, lastIndex).CamelFriendly()); descriptor.DisplayName = T(fileName.Substring(0, lastIndex).CamelFriendly());
} }
@ -182,33 +204,5 @@ namespace Orchard.Layouts.Providers {
return descriptor; return descriptor;
} }
private SnippetDescriptor DescribeSnippet(string shapeType, Snippet element) {
var shape = (dynamic)_shapeFactory.Value.Create(shapeType);
shape.Element = element;
return DescribeSnippet(shape);
}
private SnippetDescriptor DescribeSnippet(dynamic shape) {
// Execute the shape and intercept calls to the Html.SnippetField method.
var descriptor = new SnippetDescriptor();
shape.DescriptorRegistrationCallback = (Action<SnippetFieldDescriptor>)(fieldDescriptor => {
// Not using Dictionary, as that will break rendering the view for some obscure reason.
var existingDescriptor = descriptor.Fields.SingleOrDefault(x => x.Name == fieldDescriptor.Name);
if (existingDescriptor == null)
descriptor.Fields.Add(fieldDescriptor);
if (fieldDescriptor.DisplayName == null)
fieldDescriptor.DisplayName = new LocalizedString(fieldDescriptor.Name);
});
using (_currentThemeShapeBindingResolver.Value.Enable()) {
_shapeDisplay.Value.Display(shape);
}
shape.SnippetDescriptor = descriptor;
return descriptor;
}
} }
} }