Decoupling layout editor from LayoutPart.

These changes allow for better reuse of the layout editor without requiring a LayoutPart (which is simply there to store Layout state)
This commit is contained in:
Sipke Schoorstra
2014-12-18 13:18:55 +01:00
parent 829bfb094a
commit dfe066a3e6
11 changed files with 59 additions and 48 deletions

View File

@@ -53,7 +53,7 @@ namespace Orchard.Layouts.Controllers {
var categories = _elementManager.GetCategories(context).ToArray();
var viewModel = new BrowseElementsViewModel {
Categories = categories,
LayoutId = layoutId,
ContentId = layoutId,
ContentType = contentType
};
return View(viewModel);
@@ -62,16 +62,16 @@ namespace Orchard.Layouts.Controllers {
[HttpPost]
[Themed(false)]
[ValidateInput(false)]
public ShapeResult Render(string graph, string displayType, int? layoutId = null, string contentType = null, string renderEventName = null, string renderEventArgs = null) {
var context = CreateDescribeContext(layoutId, contentType);
public ShapeResult Render(string graph, string displayType, int? contentId = null, string contentType = null, string renderEventName = null, string renderEventArgs = null) {
var context = CreateDescribeContext(contentId, contentType);
var instances = _layoutSerializer.Deserialize(graph, context);
var shape = _elementDisplay.DisplayElements(instances, context.Content, displayType: displayType, updater: this, renderEventName: renderEventName, renderEventArgs: renderEventArgs);
return new ShapeResult(this, shape);
}
[Admin]
public ViewResult Create(string id, int? layoutId = null, string contentType = null) {
var describeContext = CreateDescribeContext(layoutId, contentType);
public ViewResult Create(string id, int? contentId = null, string contentType = null) {
var describeContext = CreateDescribeContext(contentId, contentType);
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, id);
var element = _elementManager.ActivateElement(descriptor);
var context = CreateEditorContext(describeContext.Content, element);
@@ -92,8 +92,8 @@ namespace Orchard.Layouts.Controllers {
[Admin]
[HttpPost]
[ValidateInput(false)]
public ViewResult Create(ElementStateViewModel model, int? layoutId = null, string contentType = null) {
var describeContext = CreateDescribeContext(layoutId, contentType);
public ViewResult Create(ElementStateViewModel model, int? contentId = null, string contentType = null) {
var describeContext = CreateDescribeContext(contentId, contentType);
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, model.TypeName);
var state = ElementStateHelper.Deserialize(model.ElementState).Combine(Request.Form.ToDictionary());
var element = _elementManager.ActivateElement(descriptor, new ActivateElementArgs { State = state });
@@ -120,8 +120,8 @@ namespace Orchard.Layouts.Controllers {
[Admin]
[HttpPost]
[ValidateInput(false)]
public ViewResult Edit(string typeName, string elementState, int? layoutId = null, string contentType = null) {
var describeContext = CreateDescribeContext(layoutId, contentType);
public ViewResult Edit(string typeName, string elementState, int? contentId = null, string contentType = null) {
var describeContext = CreateDescribeContext(contentId, contentType);
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, typeName);
var state = ElementStateHelper.Deserialize(elementState);
var element = _elementManager.ActivateElement(descriptor, new ActivateElementArgs { State = state });
@@ -143,8 +143,8 @@ namespace Orchard.Layouts.Controllers {
[Admin]
[HttpPost]
[ValidateInput(false)]
public ViewResult Update(ElementStateViewModel model, int? layoutId = null, string contentType = null) {
var describeContext = CreateDescribeContext(layoutId, contentType);
public ViewResult Update(ElementStateViewModel model, int? contentId = null, string contentType = null) {
var describeContext = CreateDescribeContext(contentId, contentType);
var descriptor = _elementManager.GetElementDescriptorByTypeName(describeContext, model.TypeName);
var state = ElementStateHelper.Deserialize(model.ElementState).Combine(Request.Form.ToDictionary(), removeNonExistingItems: true);
var element = _elementManager.ActivateElement(descriptor, new ActivateElementArgs { State = state });
@@ -190,8 +190,11 @@ namespace Orchard.Layouts.Controllers {
return context;
}
private DescribeElementsContext CreateDescribeContext(int? layoutId, string contentType) {
var part = layoutId != null && layoutId != 0 ? _contentManager.Get<ILayoutAspect>(layoutId.Value)
private DescribeElementsContext CreateDescribeContext(int? contentId = null, string contentType = null) {
if (contentId == null && contentType == null)
return DescribeElementsContext.Empty;
var part = contentId != null && contentId != 0 ? _contentManager.Get<ILayoutAspect>(contentId.Value)
?? _contentManager.New<ILayoutAspect>(contentType)
: _contentManager.New<ILayoutAspect>(contentType);

View File

@@ -48,11 +48,11 @@ namespace Orchard.Layouts.Controllers {
}
var viewModel = new LayoutEditorViewModel {
Part = layoutPart,
Templates = _layoutManager.GetTemplates().Where(x => x.Id != layoutPart.Id).ToArray(),
SelectedTemplateId = layoutPart.TemplateId,
State = state,
LayoutRoot = _layoutManager.RenderLayout(layoutPart, state, displayType: "Design"),
State = state,
LayoutRoot = _layoutManager.RenderLayout(state, displayType: "Design", content: layoutPart),
Content = layoutPart
};
var workContext = _wca.GetContext();
@@ -75,7 +75,7 @@ namespace Orchard.Layouts.Controllers {
layoutState = ApplyTemplateInternal(templateId, layoutState, layoutId, contentType);
}
var layoutShape = _layoutManager.RenderLayout(layoutPart, state: layoutState, displayType: "Design");
var layoutShape = _layoutManager.RenderLayout(state: layoutState, displayType: "Design", content: layoutPart);
return new ShapeResult(this, layoutShape);
}
@@ -95,12 +95,12 @@ namespace Orchard.Layouts.Controllers {
_shapeDisplay.Display(layout);
}
private DescribeElementsContext CreateDescribeElementsContext(int? layoutId, string contentType) {
var layoutPart = layoutId != null && layoutId != 0
? _contentManager.Get<LayoutPart>(layoutId.Value, VersionOptions.Latest) ?? _contentManager.New<LayoutPart>(contentType)
: _contentManager.New<LayoutPart>(contentType);
private DescribeElementsContext CreateDescribeElementsContext(int? contentId, string contentType) {
var content = contentId != null && contentId != 0
? _contentManager.Get(contentId.Value, VersionOptions.Latest) ?? _contentManager.New(contentType)
: _contentManager.New(contentType);
return new DescribeElementsContext { Content = layoutPart };
return new DescribeElementsContext { Content = content };
}
}
}

View File

@@ -58,9 +58,9 @@ namespace Orchard.Layouts.Drivers {
protected override DriverResult Editor(LayoutPart part, IUpdateModel updater, dynamic shapeHelper) {
return ContentShape("Parts_Layout_Edit", () => {
var viewModel = new LayoutPartViewModel {
Part = part,
State = part.LayoutState,
TemplateId = part.TemplateId,
Content = part
};
if (updater != null) {

View File

@@ -9,7 +9,15 @@ namespace Orchard.Layouts.Services {
IEnumerable<LayoutPart> GetTemplates();
LayoutPart GetLayout(int id);
IEnumerable<IElement> LoadElements(ILayoutAspect layout);
dynamic RenderLayout(ILayoutAspect layout, string state = null, string displayType = null);
/// <summary>
/// Renders the specified layout state into a shape tree.
/// </summary>
/// <param name="state">The layout state.</param>
/// <param name="displayType">Optional. The dislay type to use when rendering the elements.</param>
/// <param name="content">Optional. Provides additional context to the elements being loaded and rendered.</param>
/// <returns>A shape representing the layout to be rendered.</returns>
dynamic RenderLayout(string state, string displayType = null, IContent content = null);
/// <summary>
/// Updates the specified layout with the specified template layout.

View File

@@ -27,10 +27,10 @@ namespace Orchard.Layouts.Services {
public IEnumerable<LayoutPart> GetTemplates() {
var templateTypeNamesQuery = from typeDefinition in _contentManager.GetContentTypeDefinitions()
from typePartDefinition in typeDefinition.Parts
let settings = typePartDefinition.Settings.GetModel<LayoutTypePartSettings>()
where settings.IsTemplate
select typeDefinition.Name;
from typePartDefinition in typeDefinition.Parts
let settings = typePartDefinition.Settings.GetModel<LayoutTypePartSettings>()
where settings.IsTemplate
select typeDefinition.Name;
var templateTypeNames = templateTypeNamesQuery.ToArray();
return _contentManager.Query<LayoutPart>(templateTypeNames).List();
@@ -61,9 +61,9 @@ namespace Orchard.Layouts.Services {
context.Layout.LayoutState = _serializer.Serialize(elementTree);
}
public dynamic RenderLayout(ILayoutAspect layout, string state = null, string displayType = null) {
var elements = _serializer.Deserialize(state ?? layout.LayoutState, new DescribeElementsContext { Content = layout });
var layoutRoot = _elementDisplay.DisplayElements(elements, layout, displayType);
public dynamic RenderLayout(string state, string displayType = null, IContent content = null) {
var elements = _serializer.Deserialize(state, new DescribeElementsContext { Content = content });
var layoutRoot = _elementDisplay.DisplayElements(elements, content, displayType);
return layoutRoot;
}
@@ -125,7 +125,7 @@ namespace Orchard.Layouts.Services {
grid.Elements.Add(row);
row.Elements.Add(column);
var elements = new List<IElement> {grid};
var elements = new List<IElement> { grid };
return elements;
}

View File

@@ -4,7 +4,7 @@ using Orchard.Layouts.Framework.Elements;
namespace Orchard.Layouts.ViewModels {
public class BrowseElementsViewModel {
public IList<CategoryDescriptor> Categories { get; set; }
public int? LayoutId { get; set; }
public int? ContentId { get; set; }
public string ContentType { get; set; }
}
}

View File

@@ -1,12 +1,13 @@
using System.Collections.Generic;
using Orchard.ContentManagement;
using Orchard.Layouts.Models;
namespace Orchard.Layouts.ViewModels {
public class LayoutEditorViewModel {
public LayoutPart Part { get; set; }
public string State { get; set; }
public dynamic LayoutRoot { get; set; }
public IList<LayoutPart> Templates { get; set; }
public int? SelectedTemplateId { get; set; }
public IContent Content { get; set; }
}
}

View File

@@ -1,8 +1,8 @@
using Orchard.Layouts.Models;
using Orchard.ContentManagement;
namespace Orchard.Layouts.ViewModels {
public class LayoutPartViewModel {
public LayoutPart Part { get; set; }
public IContent Content { get; set; }
public string State { get; set; }
public string Trash { get; set; }
public int? TemplateId { get; set; }

View File

@@ -11,8 +11,8 @@
Script.Include("designer.host.js");
}
@{
var contentId = Model.Part.Id;
var contentType = Model.Part.ContentItem.ContentType;
var contentId = Model.Content != null ? Model.Content.Id : default(int?);
var contentType = Model.Content != null ? Model.Content.ContentItem.ContentType : default(string);
var url = Url.Action("Edit", "Layout", new { id = contentId, contentType = contentType, area = "Orchard.Layouts" });
var frameUrl = ViewData.ModelState.IsValid ? url : default(string);
}

View File

@@ -19,7 +19,7 @@
continue;
}
<li>
<a class="element" href="@Url.Action("Create", "Element", new { layoutId = Model.LayoutId, contentType = Model.ContentType, id = element.TypeName, area = "Orchard.Layouts" })">
<a class="element" href="@Url.Action("Create", "Element", new { layoutId = Model.ContentId, contentType = Model.ContentType, id = element.TypeName, area = "Orchard.Layouts" })">
<h2>@element.DisplayText</h2>
</a>
</li>

View File

@@ -17,15 +17,19 @@
Script.Include("frame.js");
Script.Include("serializer.js");
}
@{
var contentId = Model.Content != null ? Model.Content.Id : default(int?);
var contentType = Model.Content != null ? Model.Content.ContentItem.ContentType : default(string);
}
@Display.TokenHint()
<fieldset>
<div class="layout-editor"
data-anti-forgery-token="@Html.AntiForgeryTokenValueOrchard()"
data-render-url="@Url.Action("Render", "Element", new { layoutId = Model.Part.Id, contentType = Model.Part.ContentItem.ContentType, area = "Orchard.Layouts" })"
data-render-url="@Url.Action("Render", "Element", new { contentId = contentId, contentType = contentType, area = "Orchard.Layouts" })"
data-display-type="Design"
data-element-browser-url="@Url.Action("Browse", "Element", new { layoutId = Model.Part.Id, contentType = Model.Part.ContentItem.ContentType, area = "Orchard.Layouts" })"
data-edit-url="@Url.Action("Edit", "Element", new { layoutId = Model.Part.Id, contentType = Model.Part.ContentItem.ContentType, area = "Orchard.Layouts" })"
data-apply-template-url="@Url.Action("ApplyTemplate", "Layout", new { layoutId = Model.Part.Id, contentType = Model.Part.ContentItem.ContentType, area = "Orchard.Layouts" })"
data-element-browser-url="@Url.Action("Browse", "Element", new { contentId = contentId, contentType = contentType, area = "Orchard.Layouts" })"
data-edit-url="@Url.Action("Edit", "Element", new { contentId = contentId, contentType = contentType, area = "Orchard.Layouts" })"
data-apply-template-url="@Url.Action("ApplyTemplate", "Layout", new { contentId = contentId, contentType = contentType, area = "Orchard.Layouts" })"
data-confirm-delete-prompt="@T("Are you sure you want to delete this element?")"
data-editor-dialog-title-format="@T("$1 Properties")"
data-editor-dialog-name="Layout">
@@ -43,11 +47,6 @@
</div>
</li>
}
@*<li>
<div class="edit-layout-state">
<a class="icon icon-pencil" title="@T("View layout JSON")" href="#"></a>
</div>
</li>*@
</ol>
</div>
</div>