Making LayoutEditor a reusable editor template.

This commit is contained in:
Sipke Schoorstra
2015-02-22 09:45:49 +01:00
parent fb9ec74dfa
commit 3f15163297
6 changed files with 131 additions and 116 deletions

View File

@@ -27,12 +27,12 @@ namespace Orchard.Layouts.Drivers {
private readonly ILayoutModelMapper _mapper;
public LayoutPartDriver(
ILayoutSerializer serializer,
IElementDisplay elementDisplay,
IElementManager elementManager,
ILayoutSerializer serializer,
IElementDisplay elementDisplay,
IElementManager elementManager,
ILayoutManager layoutManager,
Lazy<IContentPartDisplay> contentPartDisplay,
IShapeDisplay shapeDisplay,
Lazy<IContentPartDisplay> contentPartDisplay,
IShapeDisplay shapeDisplay,
ILayoutModelMapper mapper) {
_serializer = serializer;
@@ -65,32 +65,34 @@ namespace Orchard.Layouts.Drivers {
protected override DriverResult Editor(LayoutPart part, IUpdateModel updater, dynamic shapeHelper) {
return ContentShape("Parts_Layout_Edit", () => {
var viewModel = new LayoutPartViewModel {
Data = _mapper.ToEditorModel(part.LayoutData, new DescribeElementsContext { Content = part}).ToJson(),
ConfigurationData = GetConfigurationData(part),
TemplateId = part.TemplateId,
Content = part,
SessionKey = part.SessionKey,
Templates = _layoutManager.GetTemplates().Where(x => x.Id != part.Id).ToArray()
LayoutEditor = new LayoutEditor {
Data = _mapper.ToEditorModel(part.LayoutData, new DescribeElementsContext { Content = part }).ToJson(),
ConfigurationData = GetConfigurationData(part),
TemplateId = part.TemplateId,
Content = part,
SessionKey = part.SessionKey,
Templates = _layoutManager.GetTemplates().Where(x => x.Id != part.Id).ToArray()
}
};
if (updater != null) {
updater.TryUpdateModel(viewModel, Prefix, null, new[] { "Part", "Templates" });
var describeContext = new DescribeElementsContext { Content = part };
var elementInstances = _mapper.ToLayoutModel(viewModel.Data, describeContext).ToArray();
var removedElementInstances = _serializer.Deserialize(viewModel.Trash, describeContext).ToArray();
var elementInstances = _mapper.ToLayoutModel(viewModel.LayoutEditor.Data, describeContext).ToArray();
var removedElementInstances = _serializer.Deserialize(viewModel.LayoutEditor.Trash, describeContext).ToArray();
var context = new LayoutSavingContext {
Content = part,
Updater = updater,
Elements = elementInstances,
RemovedElements = removedElementInstances
};
_elementManager.Saving(context);
_elementManager.Removing(context);
part.LayoutData = _serializer.Serialize(elementInstances);
part.TemplateId = viewModel.TemplateId;
part.SessionKey = viewModel.SessionKey;
part.TemplateId = viewModel.LayoutEditor.TemplateId;
part.SessionKey = viewModel.LayoutEditor.SessionKey;
}
return shapeHelper.EditorTemplate(TemplateName: "Parts.Layout", Model: viewModel, Prefix: Prefix);
@@ -120,7 +122,7 @@ namespace Orchard.Layouts.Drivers {
Session = new ImportContentContextWrapper(context)
});
});
context.ImportAttribute(part.PartDefinition.Name, "TemplateId", s => part.TemplateId = GetTemplateId(context, s));
}
@@ -151,7 +153,7 @@ namespace Orchard.Layouts.Drivers {
// If the element has no editor then the toolbox will add the element straight to to designer when being dragged & dropped,
// so we'll want to present the user with a prerendered element.
html = descriptor.EnableEditorDialog ? "" : RenderElement(element, new DescribeElementsContext { Content = part})
html = descriptor.EnableEditorDialog ? "" : RenderElement(element, new DescribeElementsContext { Content = part })
};
})
})

View File

@@ -377,6 +377,7 @@
<Content Include="Views\LayoutEditor.Template.Properties.cshtml" />
<Content Include="Views\LayoutEditor.Template.Children.cshtml" />
<Content Include="Styles\LayoutEditor.css.bundle" />
<Content Include="Views\EditorTemplates\LayoutEditor.cshtml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
@@ -505,6 +506,7 @@
<Compile Include="ViewModels\EditElementBlueprintViewModel.cs" />
<Compile Include="ViewModels\ElementWrapperPartViewModel.cs" />
<Compile Include="ViewModels\HtmlEditorViewModel.cs" />
<Compile Include="ViewModels\LayoutEditor.cs" />
<Compile Include="ViewModels\LayoutEditorPropertiesViewModel.cs" />
<Compile Include="ViewModels\VectorImageEditorViewModel.cs" />
<Compile Include="ViewModels\ImageEditorViewModel.cs" />

View File

@@ -0,0 +1,15 @@
using System.Collections.Generic;
using Orchard.ContentManagement;
using Orchard.Layouts.Models;
namespace Orchard.Layouts.ViewModels {
public class LayoutEditor {
public IContent Content { get; set; }
public string Data { get; set; }
public string ConfigurationData { get; set; }
public string Trash { get; set; }
public int? TemplateId { get; set; }
public string SessionKey { get; set; }
public IList<LayoutPart> Templates { get; set; }
}
}

View File

@@ -4,12 +4,6 @@ using Orchard.Layouts.Models;
namespace Orchard.Layouts.ViewModels {
public class LayoutPartViewModel {
public IContent Content { get; set; }
public string Data { get; set; }
public string ConfigurationData { get; set; }
public string Trash { get; set; }
public int? TemplateId { get; set; }
public string SessionKey { get; set; }
public IList<LayoutPart> Templates { get; set; }
public LayoutEditor LayoutEditor { get; set; }
}
}

View File

@@ -0,0 +1,91 @@
@using System.Globalization
@model Orchard.Layouts.ViewModels.LayoutEditor
@{
// Library dependencies.
Style.Require("jQueryUI_Orchard");
Style.Include("Lib/font-awesome.css", "Lib/font-awesome.min.css");
Style.Include("Lib/Bootstrap/bootstrap.css", "Lib/Bootstrap/bootstrap.min.css");
Script.Require("jQueryCookie");
Script.Require("jQueryUI_Draggable");
Script.Require("jQueryUI_Droppable");
Script.Require("jQueryUI_Sortable");
Script.Require("jQueryUI_Resizable");
Script.Require("jQueryUI_Position");
Script.Require("TinyMce");
Script.Require("Layouts.LayoutEditor");
Script.Include("Lib/sortable.js");
Script.Include("Lib/affix.js");
Script.Include("jquery.deserialize.js");
// Utilities.
Style.Include("dialog.css");
Script.Include("dialog.js");
Script.Include("frame.js");
Script.Include("serializer.js");
// The actual layout editor.
Style.Include("LayoutEditor.css", "LayoutEditor.min.css");
Script.Include("LayoutDesignerHost.js");
using (Script.Foot()) {
<script>
angular
.module("LayoutEditor")
.constant("environment", {
templateUrl: function(templateName) {
return "@Url.Action("Get", "Template", new { area = "Orchard.Layouts" })" + "/" + templateName;
}
});
(function() {
var editorConfig = @Html.Raw(Model.ConfigurationData);
var editorCanvasData = @Html.Raw(Model.Data);
window.layoutEditor = new LayoutEditor.Editor(editorConfig, editorCanvasData);
})(jQuery);
</script>
}
var contentId = Model.Content != null ? Model.Content.Id : default(int?);
var contentType = Model.Content != null ? Model.Content.ContentItem.ContentType : default(string);
}
<div class="layout-designer"
data-modelstate-valid="@ViewData.ModelState.IsValid.ToString().ToLower()"
data-display-type="Design"
data-edit-url="@Url.Action("Edit", "Element", new { session = Model.SessionKey, contentId = contentId, contentType = contentType, area = "Orchard.Layouts" })"
data-add-url="@Url.Action("Add", "Element", new {session = Model.SessionKey, contentId = contentId, contentType = contentType, area = "Orchard.Layouts"})"
data-add-direct-url="@Url.Action("CreateDirect", "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"
data-anti-forgery-token="@Html.AntiForgeryTokenValueOrchard()"
data-session-key="@Model.SessionKey">
@Html.HiddenFor(m => m.SessionKey)
@Html.HiddenFor(m => m.Data, new { @class = "layout-data-field" })
<fieldset>
<label>@T("Layout")</label>
<div class="group canvas-toolbar">
<div class="pull-right">
<ol class="group">
@if (Model.Templates.Any()) {
var options = Model.Templates.Select(x => new SelectListItem { Text = Html.ItemDisplayText(x).ToString(), Value = x.Id.ToString(CultureInfo.InvariantCulture), Selected = x.Id == Model.TemplateId });
<li>
<div class="template-picker">
<label>
@T("Use existing layout:")
@Html.DropDownListFor(x => x.TemplateId, options, T("(None)").Text)
</label>
</div>
</li>
}
</ol>
</div>
</div>
<div class="layout-editor-holder">
<orc-layout-editor model="window.layoutEditor" ng-app="LayoutEditor" />
</div>
</fieldset>
<div class="trash"></div>
@Display.DialogTemplate(Name: "Layout")
</div>

View File

@@ -1,91 +1,2 @@
@using System.Globalization
@model Orchard.Layouts.ViewModels.LayoutPartViewModel
@{
// Library dependencies.
Style.Require("jQueryUI_Orchard");
Style.Include("Lib/font-awesome.css", "Lib/font-awesome.min.css");
Style.Include("Lib/Bootstrap/bootstrap.css", "Lib/Bootstrap/bootstrap.min.css");
Script.Require("jQueryCookie");
Script.Require("jQueryUI_Draggable");
Script.Require("jQueryUI_Droppable");
Script.Require("jQueryUI_Sortable");
Script.Require("jQueryUI_Resizable");
Script.Require("jQueryUI_Position");
Script.Require("TinyMce");
Script.Require("Layouts.LayoutEditor");
Script.Include("Lib/sortable.js");
Script.Include("Lib/affix.js");
Script.Include("jquery.deserialize.js");
// Utilities.
Style.Include("dialog.css");
Script.Include("dialog.js");
Script.Include("frame.js");
Script.Include("serializer.js");
// The actual layout editor.
Style.Include("LayoutEditor.css", "LayoutEditor.min.css");
Script.Include("LayoutDesignerHost.js");
using (Script.Foot()) {
<script>
angular
.module("LayoutEditor")
.constant("environment", {
templateUrl: function(templateName) {
return "@Url.Action("Get", "Template", new { area = "Orchard.Layouts" })" + "/" + templateName;
}
});
(function() {
var editorConfig = @Html.Raw(Model.ConfigurationData);
var editorCanvasData = @Html.Raw(Model.Data);
window.layoutEditor = new LayoutEditor.Editor(editorConfig, editorCanvasData);
})(jQuery);
</script>
}
var contentId = Model.Content != null ? Model.Content.Id : default(int?);
var contentType = Model.Content != null ? Model.Content.ContentItem.ContentType : default(string);
}
<div class="layout-designer"
data-modelstate-valid="@ViewData.ModelState.IsValid.ToString().ToLower()"
data-display-type="Design"
data-edit-url="@Url.Action("Edit", "Element", new { session = Model.SessionKey, contentId = contentId, contentType = contentType, area = "Orchard.Layouts" })"
data-add-url="@Url.Action("Add", "Element", new {session = Model.SessionKey, contentId = contentId, contentType = contentType, area = "Orchard.Layouts"})"
data-add-direct-url="@Url.Action("CreateDirect", "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"
data-anti-forgery-token="@Html.AntiForgeryTokenValueOrchard()"
data-session-key="@Model.SessionKey">
@Html.HiddenFor(m => m.SessionKey)
@Html.HiddenFor(m => m.Data, new { @class = "layout-data-field" })
<fieldset>
<label>@T("Layout")</label>
<div class="group canvas-toolbar">
<div class="pull-right">
<ol class="group">
@if (Model.Templates.Any()) {
var options = Model.Templates.Select(x => new SelectListItem { Text = Html.ItemDisplayText(x).ToString(), Value = x.Id.ToString(CultureInfo.InvariantCulture), Selected = x.Id == Model.TemplateId });
<li>
<div class="template-picker">
<label>
@T("Use existing layout:")
@Html.DropDownListFor(x => x.TemplateId, options, T("(None)").Text)
</label>
</div>
</li>
}
</ol>
</div>
</div>
<div class="layout-editor-holder">
<orc-layout-editor model="window.layoutEditor" ng-app="LayoutEditor" />
</div>
</fieldset>
<div class="trash"></div>
@Display.DialogTemplate(Name: "Layout")
</div>
@model Orchard.Layouts.ViewModels.LayoutPartViewModel
@Html.EditorFor(m => m.LayoutEditor)