Incremental work on placeable content.

This commit is contained in:
Sipke Schoorstra
2015-09-07 11:31:33 +01:00
parent dfce6deaf1
commit 7d93bbbc10
5 changed files with 123 additions and 117 deletions

View File

@@ -2,9 +2,9 @@
using Orchard.Layouts.Helpers;
namespace Orchard.Layouts.Elements {
public class Widget : Element {
public class PlaceableContentItem : Element {
public override string Category {
get { return "Widgets"; }
get { return "Content Items"; }
}
public override bool IsSystemElement {
@@ -15,9 +15,9 @@ namespace Orchard.Layouts.Elements {
get { return false; }
}
public int? WidgetId {
get { return this.Retrieve(x => x.WidgetId); }
set { this.Store(x => x.WidgetId, value); }
public int? ContentItemId {
get { return this.Retrieve(x => x.ContentItemId); }
set { this.Store(x => x.ContentItemId, value); }
}
}
}

View File

@@ -338,7 +338,7 @@
<Compile Include="Elements\Shape.cs" />
<Compile Include="Elements\Break.cs" />
<Compile Include="Elements\UIElement.cs" />
<Compile Include="Elements\Widget.cs" />
<Compile Include="Elements\PlaceableContentItem.cs" />
<Compile Include="Filters\TokensFilter.cs" />
<Compile Include="Framework\Display\ElementDisplayedContext.cs" />
<Compile Include="Framework\Display\ElementDisplayingContext.cs" />
@@ -367,7 +367,7 @@
<Compile Include="Helpers\PrefixHelper.cs" />
<Compile Include="Helpers\JsonHelper.cs" />
<Compile Include="Helpers\StringHelper.cs" />
<Compile Include="Providers\WidgetElementHarvester.cs" />
<Compile Include="Providers\PlaceableContentElementHarvester.cs" />
<Compile Include="Recipes\Builders\CustomElementsStep.cs" />
<Compile Include="Recipes\Executors\CustomElementsStep.cs" />
<Compile Include="Providers\BlueprintElementHarvester.cs" />

View File

@@ -0,0 +1,107 @@
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.Layouts.Settings;
using Orchard.Widgets.Models;
namespace Orchard.Layouts.Providers {
public class PlaceableContentElementHarvester : Component, IElementHarvester {
private readonly Work<IContentManager> _contentManager;
public PlaceableContentElementHarvester(Work<IContentManager> contentManager) {
_contentManager = contentManager;
}
public IEnumerable<ElementDescriptor> HarvestElements(HarvestElementsContext context) {
var contentTypeDefinitions = GetPlaceableContentTypeDefinitions();
return contentTypeDefinitions.Select(contentTypeDefinition => {
var settings = contentTypeDefinition.Settings;
var description = settings.ContainsKey("Description") ? settings["Description"] : contentTypeDefinition.DisplayName;
var stereotype = settings.ContainsKey("Stereotype") ? settings["Stereotype"] : default(string);
var category = GetCategoryFromStereotype(stereotype);
return new ElementDescriptor(typeof (PlaceableContentItem), contentTypeDefinition.Name, T(contentTypeDefinition.DisplayName), T(description), category) {
Displaying = Displaying,
Editor = Editor,
UpdateEditor = UpdateEditor,
ToolboxIcon = "\uf1b2",
EnableEditorDialog = true,
StateBag = new Dictionary<string, object> {
{ "ContentTypeName", contentTypeDefinition.Name }
}
};
});
}
private void Displaying(ElementDisplayingContext context) {
var contentTypeName = (string)context.Element.Descriptor.StateBag["ContentTypeName"];
var element = (PlaceableContentItem)context.Element;
var contentItemId = element.ContentItemId;
var contentItem = contentItemId != null
? _contentManager.Value.Get(contentItemId.Value, VersionOptions.Published)
: _contentManager.Value.New(contentTypeName);
var contentShape = contentItem != null ? _contentManager.Value.BuildDisplay(contentItem) : default(dynamic);
context.ElementShape.ContentItem = contentItem;
context.ElementShape.ContentShape = contentShape;
}
private void Editor(ElementEditorContext context) {
UpdateEditor(context);
}
private void UpdateEditor(ElementEditorContext context) {
var contentTypeName = (string)context.Element.Descriptor.StateBag["ContentTypeName"];
var element = (PlaceableContentItem) context.Element;
var contentItemId = element.ContentItemId;
var contentItem = contentItemId != null
? _contentManager.Value.Get(contentItemId.Value, VersionOptions.Latest)
: _contentManager.Value.New(contentTypeName);
dynamic contentEditorShape;
if (context.Updater != null) {
if (contentItem.Id == 0) {
_contentManager.Value.Create(contentItem, VersionOptions.Draft);
element.ContentItemId = contentItem.Id;
}
else {
contentItem = _contentManager.Value.Get(contentItem.Id, VersionOptions.DraftRequired);
}
contentEditorShape = _contentManager.Value.UpdateEditor(contentItem, context.Updater);
}
else {
contentEditorShape = _contentManager.Value.BuildEditor(contentItem);
}
contentEditorShape.Metadata.Position = "Properties:0";
context.EditorResult.Add(contentEditorShape);
}
private IEnumerable<ContentTypeDefinition> GetPlaceableContentTypeDefinitions() {
var contentTypeDefinitionsQuery =
from contentTypeDefinition in _contentManager.Value.GetContentTypeDefinitions()
where contentTypeDefinition.Settings.GetModel<ContentTypeLayoutSettings>().Placeable
select contentTypeDefinition;
return contentTypeDefinitionsQuery.ToList();
}
private string GetCategoryFromStereotype(string stereotype) {
switch (stereotype) {
case "Widget":
return "Widgets";
default:
return "Content Items";
}
}
}
}

View File

@@ -1,101 +0,0 @@
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

@@ -56,20 +56,20 @@ namespace Orchard.Layouts.Services {
public IEnumerable<CategoryDescriptor> GetCategories(DescribeElementsContext context) {
var contentType = context.Content != null ? context.Content.ContentItem.ContentType : default(string);
return _cacheManager.Get(String.Format("ElementCategories-{0}-{1}", contentType ?? "AnyType", context.CacheVaryParam), acquireContext => {
var elements = DescribeElements(context);
var elementDescriptors = DescribeElements(context);
var categoryDictionary = GetCategories();
var categoryDescriptorDictionary = new Dictionary<string, CategoryDescriptor>();
foreach (var element in elements) {
var category = categoryDictionary.ContainsKey(element.Category)
? categoryDictionary[element.Category]
: new Category(element.Category, T(element.Category), position: int.MaxValue);
foreach (var elementDescriptor in elementDescriptors) {
var category = categoryDictionary.ContainsKey(elementDescriptor.Category)
? categoryDictionary[elementDescriptor.Category]
: new Category(elementDescriptor.Category, T(elementDescriptor.Category), position: int.MaxValue);
var descriptor = categoryDescriptorDictionary.ContainsKey(element.Category)
? categoryDescriptorDictionary[element.Category]
: categoryDescriptorDictionary[element.Category] = new CategoryDescriptor(category.Name, category.DisplayName, category.Description, category.Position);
var descriptor = categoryDescriptorDictionary.ContainsKey(elementDescriptor.Category)
? categoryDescriptorDictionary[elementDescriptor.Category]
: categoryDescriptorDictionary[elementDescriptor.Category] = new CategoryDescriptor(category.Name, category.DisplayName, category.Description, category.Position);
descriptor.Elements.Add(element);
descriptor.Elements.Add(elementDescriptor);
}
acquireContext.Monitor(_signals.When(Signals.ElementDescriptors));