Implemented a Widget element harvester.

This commit is contained in:
Sipke Schoorstra
2015-08-22 16:59:17 +01:00
parent 47ac6ba0ad
commit de3d205ca9
5 changed files with 148 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Helpers;
namespace Orchard.Layouts.Elements {
public class Widget : Element {
public override string Category {
get { return "Widgets"; }
}
public override bool IsSystemElement {
get { return true; }
}
public override bool HasEditor {
get { return false; }
}
public int? WidgetId {
get { return this.Retrieve(x => x.WidgetId); }
set { this.Store(x => x.WidgetId, value); }
}
}
}

View File

@@ -339,6 +339,7 @@
<Compile Include="Elements\Shape.cs" />
<Compile Include="Elements\Break.cs" />
<Compile Include="Elements\UIElement.cs" />
<Compile Include="Elements\Widget.cs" />
<Compile Include="Filters\TokensFilter.cs" />
<Compile Include="Framework\Display\ElementDisplayedContext.cs" />
<Compile Include="Framework\Display\ElementDisplayingContext.cs" />
@@ -367,6 +368,7 @@
<Compile Include="Helpers\PrefixHelper.cs" />
<Compile Include="Helpers\JsonHelper.cs" />
<Compile Include="Helpers\StringHelper.cs" />
<Compile Include="Providers\WidgetElementHarvester.cs" />
<Compile Include="Recipes\Builders\CustomElementsStep.cs" />
<Compile Include="Recipes\Executors\CustomElementsStep.cs" />
<Compile Include="Providers\BlueprintElementHarvester.cs" />
@@ -590,6 +592,12 @@
<ItemGroup>
<Folder Include="Assets\CSS\" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\Elements\Widget.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\Elements\Widget.Design.cshtml" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

View File

@@ -0,0 +1,101 @@
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.Environment;
using Orchard.Layouts.Elements;
using Orchard.Layouts.Framework.Display;
using Orchard.Layouts.Framework.Drivers;
using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Framework.Harvesters;
using Orchard.Widgets.Models;
namespace Orchard.Layouts.Providers {
public class WidgetElementHarvester : Component, IElementHarvester {
private readonly Work<IContentManager> _contentManager;
public WidgetElementHarvester(Work<IContentManager> contentManager) {
_contentManager = contentManager;
}
public IEnumerable<ElementDescriptor> HarvestElements(HarvestElementsContext context) {
var widgetTypeDefinitions = GetWidgetContentTypeDefinitions();
return widgetTypeDefinitions.Select(widgetTypeDefinition => {
var widgetDescription = widgetTypeDefinition.Settings.ContainsKey("Description") ? widgetTypeDefinition.Settings["Description"] : widgetTypeDefinition.DisplayName;
return new ElementDescriptor(typeof (Widget), widgetTypeDefinition.Name, T(widgetTypeDefinition.DisplayName), T(widgetDescription), "Widgets") {
Displaying = Displaying,
Editor = Editor,
UpdateEditor = UpdateEditor,
ToolboxIcon = "\uf1b2",
EnableEditorDialog = true,
StateBag = new Dictionary<string, object> {
{ "ContentTypeName", widgetTypeDefinition.Name }
}
};
});
}
private void Displaying(ElementDisplayingContext context) {
var contentTypeName = (string)context.Element.Descriptor.StateBag["ContentTypeName"];
var element = (Widget)context.Element;
var widgetId = element.WidgetId;
var widgetPart = widgetId != null
? _contentManager.Value.Get<WidgetPart>(widgetId.Value, VersionOptions.Published)
: _contentManager.Value.New<WidgetPart>(contentTypeName);
var widgetShape = widgetPart != null ? _contentManager.Value.BuildDisplay(widgetPart) : default(dynamic);
context.ElementShape.WidgetPart = widgetPart;
context.ElementShape.WidgetShape = widgetShape;
}
private void Editor(ElementEditorContext context) {
UpdateEditor(context);
}
private void UpdateEditor(ElementEditorContext context) {
var contentTypeName = (string)context.Element.Descriptor.StateBag["ContentTypeName"];
var element = (Widget) context.Element;
var widgetId = element.WidgetId;
var widgetPart = widgetId != null
? _contentManager.Value.Get<WidgetPart>(widgetId.Value, VersionOptions.Latest)
: _contentManager.Value.New<WidgetPart>(contentTypeName);
// Set dummy layer, zone and position.
var hiddenLayer = _contentManager.Value.Query<LayerPart, LayerPartRecord>("Layer").Where(x => x.Name == "Disabled").Slice(1).Single();
widgetPart.LayerPart = hiddenLayer;
widgetPart.Zone = "Elements";
widgetPart.Position = "1";
dynamic widgetEditorShape;
if (context.Updater != null) {
if (widgetPart.Id == 0) {
_contentManager.Value.Create(widgetPart, VersionOptions.Draft);
element.WidgetId = widgetPart.Id;
}
else {
widgetPart = _contentManager.Value.Get<WidgetPart>(widgetPart.Id, VersionOptions.DraftRequired);
}
widgetEditorShape = _contentManager.Value.UpdateEditor(widgetPart, context.Updater);
}
else {
widgetEditorShape = _contentManager.Value.BuildEditor(widgetPart);
}
widgetEditorShape.Metadata.Position = "Properties:0";
context.EditorResult.Add(widgetEditorShape);
}
private IEnumerable<ContentTypeDefinition> GetWidgetContentTypeDefinitions() {
var widgetTypeDefinitionsQuery =
from contentTypeDefinition in _contentManager.Value.GetContentTypeDefinitions()
where contentTypeDefinition.Settings.ContainsKey("Stereotype") && contentTypeDefinition.Settings["Stereotype"] == "Widget"
select contentTypeDefinition;
return widgetTypeDefinitionsQuery.ToList();
}
}
}

View File

@@ -0,0 +1,7 @@
@using Orchard.Widgets.Models
@{
var widgetPart = (WidgetPart)Model.WidgetPart;
}
<div class="layout-placeholder">
@String.Format("{0} - {1}", widgetPart.Title, widgetPart.ContentItem.TypeDefinition.DisplayName)
</div>

View File

@@ -0,0 +1,9 @@
@using Orchard.Layouts.Helpers
@{
var tagBuilder = TagBuilderExtensions.CreateElementTagBuilder(Model);
}
@tagBuilder.StartElement
@if (Model.WidgetShape != null) {
@Display(Model.WidgetShape)
}
@tagBuilder.EndElement