mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Incremental work on blending layouts, zones and widgets.
This commit is contained in:
@@ -1,37 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Forms.Services;
|
||||
using Orchard.Layouts.Elements;
|
||||
using Orchard.Layouts.Elements;
|
||||
using Orchard.Layouts.Framework.Drivers;
|
||||
|
||||
namespace Orchard.Layouts.Drivers {
|
||||
public class ColumnElementDriver : FormsElementDriver<Column> {
|
||||
public ColumnElementDriver(IFormManager formManager) : base(formManager) {
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> FormNames {
|
||||
get {
|
||||
yield return "Column";
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DescribeForm(DescribeContext context) {
|
||||
context.Form("Column", factory => {
|
||||
var shape = (dynamic)factory;
|
||||
var form = shape.Fieldset(
|
||||
Id: "Column",
|
||||
_Span: shape.Textbox(
|
||||
Id: "ColumnSpan",
|
||||
Name: "ColumnSpan",
|
||||
Title: "Span",
|
||||
Description: T("The column span.")),
|
||||
_Offset: shape.Textbox(
|
||||
Id: "ColumnOffset",
|
||||
Name: "ColumnOffset",
|
||||
Title: "Offset",
|
||||
Description: T("The column offset expressed in span size.")));
|
||||
|
||||
return form;
|
||||
});
|
||||
}
|
||||
}
|
||||
public class ColumnElementDriver : ElementDriver<Column> {}
|
||||
}
|
@@ -4,7 +4,7 @@ using Orchard.Localization;
|
||||
|
||||
namespace Orchard.Layouts.Elements {
|
||||
public class Column : Container {
|
||||
|
||||
|
||||
public override string Category {
|
||||
get { return "Layout"; }
|
||||
}
|
||||
@@ -22,7 +22,7 @@ namespace Orchard.Layouts.Elements {
|
||||
}
|
||||
|
||||
public int? Width {
|
||||
get { return this.Retrieve<int?>("Width") ?? this.Retrieve<int?>("ColumnSpan") ?? 0; } // Falling back on "ColumnSpan" for backward compatibility.
|
||||
get { return this.Retrieve<int?>("Width") ?? this.Retrieve<int?>("ColumnSpan") ?? 0; } // Falling back on "ColumnSpan" for backward compatibility.
|
||||
set { this.Store(x => x.Width, value); }
|
||||
}
|
||||
|
||||
@@ -34,5 +34,10 @@ namespace Orchard.Layouts.Elements {
|
||||
public int Size {
|
||||
get { return Width.GetValueOrDefault() + Offset.GetValueOrDefault(); }
|
||||
}
|
||||
|
||||
public string ZoneName {
|
||||
get { return this.Retrieve(x => x.ZoneName); }
|
||||
set { this.Store(x => x.ZoneName, value); }
|
||||
}
|
||||
}
|
||||
}
|
@@ -42,7 +42,6 @@ namespace Orchard.Layouts.Framework.Display {
|
||||
var drivers = element.Descriptor.GetDrivers();
|
||||
var elementShapeArguments = CreateArguments(element, content);
|
||||
var elementShape = (dynamic)_shapeFactory.Create("Element", elementShapeArguments, () => new ZoneHolding(() => _shapeFactory.Create("ElementZone")));
|
||||
|
||||
|
||||
elementShape.Metadata.DisplayType = displayType;
|
||||
elementShape.Metadata.Alternates.Add(String.Format("Elements_{0}", typeName));
|
||||
|
@@ -726,13 +726,13 @@ var LayoutEditor;
|
||||
})(LayoutEditor || (LayoutEditor = {}));
|
||||
var LayoutEditor;
|
||||
(function (LayoutEditor) {
|
||||
|
||||
LayoutEditor.Column = function (data, htmlId, htmlClass, htmlStyle, isTemplated, width, offset, children) {
|
||||
LayoutEditor.Column = function (data, htmlId, htmlClass, htmlStyle, isTemplated, width, offset, zoneName, children) {
|
||||
LayoutEditor.Element.call(this, "Column", data, htmlId, htmlClass, htmlStyle, isTemplated);
|
||||
LayoutEditor.Container.call(this, ["Grid", "Content"], children);
|
||||
|
||||
this.width = width;
|
||||
this.offset = offset;
|
||||
this.zoneName = zoneName;
|
||||
|
||||
var _hasPendingChange = false;
|
||||
var _origWidth = 0;
|
||||
@@ -740,7 +740,7 @@ var LayoutEditor;
|
||||
|
||||
this.beginChange = function () {
|
||||
if (!!_hasPendingChange)
|
||||
throw new Error("Column already has a pending change.")
|
||||
throw new Error("Column already has a pending change.");
|
||||
_hasPendingChange = true;
|
||||
_origWidth = this.width;
|
||||
_origOffset = this.offset;
|
||||
@@ -748,7 +748,7 @@ var LayoutEditor;
|
||||
|
||||
this.commitChange = function () {
|
||||
if (!_hasPendingChange)
|
||||
throw new Error("Column has no pending change.")
|
||||
throw new Error("Column has no pending change.");
|
||||
_origWidth = 0;
|
||||
_origOffset = 0;
|
||||
_hasPendingChange = false;
|
||||
@@ -756,7 +756,7 @@ var LayoutEditor;
|
||||
|
||||
this.rollbackChange = function () {
|
||||
if (!_hasPendingChange)
|
||||
throw new Error("Column has no pending change.")
|
||||
throw new Error("Column has no pending change.");
|
||||
this.width = _origWidth;
|
||||
this.offset = _origOffset;
|
||||
_origWidth = 0;
|
||||
@@ -782,7 +782,7 @@ var LayoutEditor;
|
||||
offset: 0,
|
||||
children: []
|
||||
});
|
||||
|
||||
|
||||
this.width = this.width - newColumnWidth;
|
||||
this.parent.insertChild(newColumn, this);
|
||||
newColumn.setIsFocused();
|
||||
@@ -824,6 +824,7 @@ var LayoutEditor;
|
||||
var result = this.elementToObject();
|
||||
result.width = this.width;
|
||||
result.offset = this.offset;
|
||||
result.zoneName = this.zoneName;
|
||||
result.children = this.childrenToObject();
|
||||
return result;
|
||||
};
|
||||
@@ -838,6 +839,7 @@ var LayoutEditor;
|
||||
value.isTemplated,
|
||||
value.width,
|
||||
value.offset,
|
||||
value.zoneName,
|
||||
LayoutEditor.childrenFrom(value.children));
|
||||
result.toolboxIcon = value.toolboxIcon;
|
||||
result.toolboxLabel = value.toolboxLabel;
|
||||
@@ -854,11 +856,11 @@ var LayoutEditor;
|
||||
isTemplated: false,
|
||||
width: 12 / value,
|
||||
offset: 0,
|
||||
zoneName: null,
|
||||
children: []
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
})(LayoutEditor || (LayoutEditor = {}));
|
||||
var LayoutEditor;
|
||||
(function (LayoutEditor) {
|
||||
|
File diff suppressed because one or more lines are too long
@@ -1,12 +1,12 @@
|
||||
var LayoutEditor;
|
||||
(function (LayoutEditor) {
|
||||
|
||||
LayoutEditor.Column = function (data, htmlId, htmlClass, htmlStyle, isTemplated, width, offset, children) {
|
||||
LayoutEditor.Column = function (data, htmlId, htmlClass, htmlStyle, isTemplated, width, offset, zoneName, children) {
|
||||
LayoutEditor.Element.call(this, "Column", data, htmlId, htmlClass, htmlStyle, isTemplated);
|
||||
LayoutEditor.Container.call(this, ["Grid", "Content"], children);
|
||||
|
||||
this.width = width;
|
||||
this.offset = offset;
|
||||
this.zoneName = zoneName;
|
||||
|
||||
var _hasPendingChange = false;
|
||||
var _origWidth = 0;
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
this.beginChange = function () {
|
||||
if (!!_hasPendingChange)
|
||||
throw new Error("Column already has a pending change.")
|
||||
throw new Error("Column already has a pending change.");
|
||||
_hasPendingChange = true;
|
||||
_origWidth = this.width;
|
||||
_origOffset = this.offset;
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
this.commitChange = function () {
|
||||
if (!_hasPendingChange)
|
||||
throw new Error("Column has no pending change.")
|
||||
throw new Error("Column has no pending change.");
|
||||
_origWidth = 0;
|
||||
_origOffset = 0;
|
||||
_hasPendingChange = false;
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
this.rollbackChange = function () {
|
||||
if (!_hasPendingChange)
|
||||
throw new Error("Column has no pending change.")
|
||||
throw new Error("Column has no pending change.");
|
||||
this.width = _origWidth;
|
||||
this.offset = _origOffset;
|
||||
_origWidth = 0;
|
||||
@@ -56,7 +56,7 @@
|
||||
offset: 0,
|
||||
children: []
|
||||
});
|
||||
|
||||
|
||||
this.width = this.width - newColumnWidth;
|
||||
this.parent.insertChild(newColumn, this);
|
||||
newColumn.setIsFocused();
|
||||
@@ -98,6 +98,7 @@
|
||||
var result = this.elementToObject();
|
||||
result.width = this.width;
|
||||
result.offset = this.offset;
|
||||
result.zoneName = this.zoneName;
|
||||
result.children = this.childrenToObject();
|
||||
return result;
|
||||
};
|
||||
@@ -112,6 +113,7 @@
|
||||
value.isTemplated,
|
||||
value.width,
|
||||
value.offset,
|
||||
value.zoneName,
|
||||
LayoutEditor.childrenFrom(value.children));
|
||||
result.toolboxIcon = value.toolboxIcon;
|
||||
result.toolboxLabel = value.toolboxLabel;
|
||||
@@ -128,9 +130,9 @@
|
||||
isTemplated: false,
|
||||
width: 12 / value,
|
||||
offset: 0,
|
||||
zoneName: null,
|
||||
children: []
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
})(LayoutEditor || (LayoutEditor = {}));
|
@@ -55,12 +55,14 @@ namespace Orchard.Layouts.Services {
|
||||
base.ToElement(element, node);
|
||||
element.Width = (int?)node["width"];
|
||||
element.Offset = (int?)node["offset"];
|
||||
element.ZoneName = (string) node["zoneName"];
|
||||
}
|
||||
|
||||
public override void FromElement(Column element, DescribeElementsContext describeContext, JToken node) {
|
||||
base.FromElement(element, describeContext, node);
|
||||
node["width"] = element.Width;
|
||||
node["offset"] = element.Offset;
|
||||
node["zoneName"] = element.ZoneName;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -46,5 +46,10 @@ namespace Orchard.Layouts.Services {
|
||||
IEnumerable<Element> CreateDefaultLayout();
|
||||
void Exporting(ExportLayoutContext context);
|
||||
void Importing(ImportLayoutContext context);
|
||||
|
||||
/// <summary>
|
||||
/// Collects all zones as defined in all layouts in the system.
|
||||
/// </summary>
|
||||
IEnumerable<string> GetZones();
|
||||
}
|
||||
}
|
@@ -60,6 +60,21 @@ namespace Orchard.Layouts.Services {
|
||||
context.Layout.LayoutData = _serializer.Serialize(elementTree);
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetZones() {
|
||||
var layouts = GetTemplates().ToList();
|
||||
var zoneNames = new HashSet<string>();
|
||||
|
||||
foreach (var layoutPart in layouts) {
|
||||
var elements = LoadElements(layoutPart).Flatten();
|
||||
var columns = elements.Where(x => x is Column).Cast<Column>().Where(x => !String.IsNullOrWhiteSpace(x.ZoneName)).ToList();
|
||||
|
||||
foreach (var column in columns)
|
||||
zoneNames.Add(column.ZoneName);
|
||||
}
|
||||
|
||||
return zoneNames;
|
||||
}
|
||||
|
||||
public dynamic RenderLayout(string data, string displayType = null, IContent content = null) {
|
||||
var elements = _serializer.Deserialize(data, new DescribeElementsContext { Content = content });
|
||||
var layoutRoot = _elementDisplay.DisplayElements(elements, content, displayType);
|
||||
|
@@ -1,5 +1,4 @@
|
||||
@using Orchard.Layouts.ViewModels;
|
||||
<div class="layout-element-wrapper" ng-class="{'layout-container-empty': getShowChildrenPlaceholder()}">
|
||||
<div class="layout-element-wrapper" ng-class="{'layout-container-empty': getShowChildrenPlaceholder()}">
|
||||
<ul class="layout-panel layout-panel-main">
|
||||
<li class="layout-panel-item layout-panel-label">Canvas</li>
|
||||
@Display()
|
||||
|
@@ -1,8 +1,16 @@
|
||||
@using Orchard.Layouts.ViewModels;
|
||||
@using Orchard.Layouts.ViewModels
|
||||
@{
|
||||
var additionalItems = new[] {
|
||||
new LayoutEditorPropertiesItem() {
|
||||
Label = "Zone Name:",
|
||||
Model = "element.zoneName"
|
||||
}
|
||||
};
|
||||
}
|
||||
<div class="layout-element-wrapper" ng-class="{'layout-container-empty': getShowChildrenPlaceholder()}">
|
||||
<ul class="layout-panel layout-panel-main">
|
||||
<li class="layout-panel-item layout-panel-label">Column ({{element.width}})</li>
|
||||
@Display(New.LayoutEditor_Template_Properties(ElementTypeName: "column"))
|
||||
@Display(New.LayoutEditor_Template_Properties(ElementTypeName: "column", Items: additionalItems))
|
||||
<li class="layout-panel-item layout-panel-action" title="@T("Delete column (Del)")" ng-click="delete(element)"><i class="fa fa-remove"></i></li>
|
||||
<li class="layout-panel-item layout-panel-action" title="@T("Move column left (Ctrl+Left)")" ng-click="element.moveUp()" ng-class="{disabled: !element.canMoveUp()}"><i class="fa fa-chevron-left"></i></li>
|
||||
<li class="layout-panel-item layout-panel-action" title="@T("Move column right (Ctrl+Right)")" ng-click="element.moveDown()" ng-class="{disabled: !element.canMoveDown()}"><i class="fa fa-chevron-right"></i></li>
|
||||
|
@@ -1,15 +1,22 @@
|
||||
@using Orchard.Layouts.ViewModels;
|
||||
<div class="layout-element-wrapper" ng-class="{'layout-container-empty': getShowChildrenPlaceholder()}">
|
||||
<div class="layout-element-wrapper" ng-class="{'layout-container-empty': getShowChildrenPlaceholder()}">
|
||||
<ul class="layout-panel layout-panel-main">
|
||||
<li class="layout-panel-item layout-panel-label">Row</li>
|
||||
@Display(New.LayoutEditor_Template_Properties(ElementTypeName: "row"))
|
||||
<li class="layout-panel-item layout-panel-action" title="@T("Delete row (Del)")" ng-click="delete(element)"><i class="fa fa-remove"></i></li>
|
||||
<li class="layout-panel-item layout-panel-action" title="@T("Move row up (Ctrl+Up)")" ng-click="element.moveUp()" ng-class="{disabled: !element.canMoveUp()}"><i class="fa fa-chevron-up"></i></li>
|
||||
<li class="layout-panel-item layout-panel-action" title="@T("Move row down (Ctrl+Down)")" ng-click="element.moveDown()" ng-class="{disabled: !element.canMoveDown()}"><i class="fa fa-chevron-down"></i></li>
|
||||
<li class="layout-panel-item layout-panel-action" title="@T("Distribute columns evenly")" ng-click="element.evenColumns()" ng-class="{disabled: element.children.length == 0}"><i class="fa fa-columns"></i></li>
|
||||
<li class="layout-panel-item layout-panel-action" title="@T("Delete row (Del)")" ng-click="delete(element)">
|
||||
<i class="fa fa-remove"></i>
|
||||
</li>
|
||||
<li class="layout-panel-item layout-panel-action" title="@T("Move row up (Ctrl+Up)")" ng-click="element.moveUp()" ng-class="{disabled: !element.canMoveUp()}">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
</li>
|
||||
<li class="layout-panel-item layout-panel-action" title="@T("Move row down (Ctrl+Down)")" ng-click="element.moveDown()" ng-class="{disabled: !element.canMoveDown()}">
|
||||
<i class="fa fa-chevron-down"></i>
|
||||
</li>
|
||||
<li class="layout-panel-item layout-panel-action" title="@T("Distribute columns evenly")" ng-click="element.evenColumns()" ng-class="{disabled: element.children.length == 0}">
|
||||
<i class="fa fa-columns"></i>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="layout-container-children-placeholder">
|
||||
@T("Drag a column element from the toolbox and drop it here to add a column.")
|
||||
</div>
|
||||
@Display(New.LayoutEditor_Template_Children())
|
||||
</div>
|
||||
</div>
|
@@ -18,6 +18,7 @@ using Orchard.Widgets.Models;
|
||||
using Orchard.Widgets.Services;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Contents.Settings;
|
||||
using Orchard.Layouts.Services;
|
||||
using Orchard.Localization.Services;
|
||||
|
||||
namespace Orchard.Widgets.Controllers {
|
||||
@@ -29,6 +30,7 @@ namespace Orchard.Widgets.Controllers {
|
||||
private readonly ISiteThemeService _siteThemeService;
|
||||
private readonly IVirtualPathProvider _virtualPathProvider;
|
||||
private readonly ICultureManager _cultureManager;
|
||||
private readonly ILayoutManager _layoutManager;
|
||||
|
||||
public AdminController(
|
||||
IOrchardServices services,
|
||||
@@ -36,13 +38,15 @@ namespace Orchard.Widgets.Controllers {
|
||||
IShapeFactory shapeFactory,
|
||||
ISiteThemeService siteThemeService,
|
||||
IVirtualPathProvider virtualPathProvider,
|
||||
ICultureManager cultureManager) {
|
||||
ICultureManager cultureManager,
|
||||
ILayoutManager layoutManager) {
|
||||
|
||||
Services = services;
|
||||
_widgetsService = widgetsService;
|
||||
_siteThemeService = siteThemeService;
|
||||
_virtualPathProvider = virtualPathProvider;
|
||||
_cultureManager = cultureManager;
|
||||
_layoutManager = layoutManager;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
@@ -55,20 +59,20 @@ namespace Orchard.Widgets.Controllers {
|
||||
dynamic Shape { get; set; }
|
||||
|
||||
public ActionResult Index(int? layerId, string culture) {
|
||||
ExtensionDescriptor currentTheme = _siteThemeService.GetSiteTheme();
|
||||
var currentTheme = _siteThemeService.GetSiteTheme();
|
||||
if (currentTheme == null) {
|
||||
Services.Notifier.Error(T("To manage widgets you must have a theme enabled."));
|
||||
return RedirectToAction("Index", "Admin", new { area = "Dashboard" });
|
||||
}
|
||||
|
||||
IEnumerable<LayerPart> layers = _widgetsService.GetLayers().ToList();
|
||||
var layers = _widgetsService.GetLayers().ToList();
|
||||
|
||||
if (!layers.Any()) {
|
||||
Services.Notifier.Error(T("There are no widget layers defined. A layer will need to be added in order to add widgets to any part of the site."));
|
||||
return RedirectToAction("AddLayer");
|
||||
}
|
||||
|
||||
LayerPart currentLayer = layerId == null
|
||||
var currentLayer = layerId == null
|
||||
? layers.FirstOrDefault()
|
||||
: layers.FirstOrDefault(layer => layer.Id == layerId);
|
||||
|
||||
@@ -77,12 +81,11 @@ namespace Orchard.Widgets.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
IEnumerable<string> allZones = _widgetsService.GetZones();
|
||||
IEnumerable<string> currentThemesZones = _widgetsService.GetZones(currentTheme);
|
||||
|
||||
string zonePreviewImagePath = string.Format("{0}/{1}/ThemeZonePreview.png", currentTheme.Location, currentTheme.Id);
|
||||
string zonePreviewImage = _virtualPathProvider.FileExists(zonePreviewImagePath) ? zonePreviewImagePath : null;
|
||||
|
||||
var allZones = _widgetsService.GetZones();
|
||||
var currentThemesZones = _widgetsService.GetZones(currentTheme);
|
||||
var layoutZones = _layoutManager.GetZones().ToList();
|
||||
var zonePreviewImagePath = string.Format("{0}/{1}/ThemeZonePreview.png", currentTheme.Location, currentTheme.Id);
|
||||
var zonePreviewImage = _virtualPathProvider.FileExists(zonePreviewImagePath) ? zonePreviewImagePath : null;
|
||||
var widgets = _widgetsService.GetWidgets();
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(culture)) {
|
||||
@@ -101,7 +104,8 @@ namespace Orchard.Widgets.Controllers {
|
||||
.CurrentCulture(culture)
|
||||
.Layers(layers)
|
||||
.Widgets(widgets)
|
||||
.Zones(currentThemesZones)
|
||||
.ThemeZones(currentThemesZones)
|
||||
.LayoutZones(layoutZones)
|
||||
.Cultures(_cultureManager.ListCultures())
|
||||
.OrphanZones(allZones.Except(currentThemesZones))
|
||||
.OrphanWidgets(_widgetsService.GetOrphanedWidgets())
|
||||
|
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Settings.Models;
|
||||
using Orchard.Layouts.Elements;
|
||||
using Orchard.Layouts.Framework.Display;
|
||||
using Orchard.Layouts.Framework.Drivers;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Widgets.Models;
|
||||
using Orchard.Widgets.Services;
|
||||
|
||||
namespace Orchard.Widgets.Drivers {
|
||||
public class ColumnElementDriver : ElementDriver<Column> {
|
||||
private readonly IOrchardServices _orchardServices;
|
||||
private readonly IRuleManager _ruleManager;
|
||||
private readonly IWidgetsService _widgetsService;
|
||||
|
||||
public ColumnElementDriver(IOrchardServices orchardServices, IRuleManager ruleManager, IWidgetsService widgetsService) {
|
||||
_orchardServices = orchardServices;
|
||||
_ruleManager = ruleManager;
|
||||
_widgetsService = widgetsService;
|
||||
}
|
||||
|
||||
protected override void OnDisplaying(Column element, ElementDisplayContext context) {
|
||||
var zoneName = element.ZoneName;
|
||||
|
||||
if (String.IsNullOrWhiteSpace(zoneName))
|
||||
return;
|
||||
|
||||
var activeLayers = _orchardServices.ContentManager.Query<LayerPart>().ForType("Layer").List();
|
||||
var activeLayerIds = new List<int>();
|
||||
|
||||
foreach (var activeLayer in activeLayers) {
|
||||
try {
|
||||
if (_ruleManager.Matches(activeLayer.LayerRule)) {
|
||||
activeLayerIds.Add(activeLayer.ContentItem.Id);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
Logger.Warning(e, T("An error occured during layer evaluation on: {0}", activeLayer.Name).Text);
|
||||
}
|
||||
}
|
||||
|
||||
var widgetParts = _widgetsService.GetWidgets(layerIds: activeLayerIds.ToArray()).Where(x => x.Zone == zoneName);
|
||||
var defaultCulture = _orchardServices.WorkContext.CurrentSite.As<SiteSettingsPart>().SiteCulture;
|
||||
var currentCulture = _orchardServices.WorkContext.CurrentCulture;
|
||||
|
||||
foreach (var widgetPart in widgetParts) {
|
||||
var commonPart = widgetPart.As<ICommonPart>();
|
||||
if (commonPart == null || commonPart.Container == null) {
|
||||
Logger.Warning("The widget '{0}' is has no assigned layer or the layer does not exist.", widgetPart.Title);
|
||||
continue;
|
||||
}
|
||||
|
||||
// ignore widget for different cultures
|
||||
var localizablePart = widgetPart.As<ILocalizableAspect>();
|
||||
if (localizablePart != null) {
|
||||
// if localized culture is null then show if current culture is the default
|
||||
// this allows a user to show a content item for the default culture only
|
||||
if (localizablePart.Culture == null && defaultCulture != currentCulture) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if culture is set, show only if current culture is the same
|
||||
if (localizablePart.Culture != null && localizablePart.Culture != currentCulture) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// check permissions
|
||||
if (!_orchardServices.Authorizer.Authorize(Core.Contents.Permissions.ViewContent, widgetPart)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var widgetShape = _orchardServices.ContentManager.BuildDisplay(widgetPart);
|
||||
|
||||
context.ElementShape.Add(widgetShape, widgetPart.Position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Layouts.Services;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Utility.Extensions;
|
||||
using Orchard.Widgets.Models;
|
||||
@@ -12,10 +13,12 @@ namespace Orchard.Widgets.Drivers {
|
||||
public class WidgetPartDriver : ContentPartDriver<WidgetPart> {
|
||||
private readonly IWidgetsService _widgetsService;
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly ILayoutManager _layoutManager;
|
||||
|
||||
public WidgetPartDriver(IWidgetsService widgetsService, IContentManager contentManager) {
|
||||
public WidgetPartDriver(IWidgetsService widgetsService, IContentManager contentManager, ILayoutManager layoutManager) {
|
||||
_widgetsService = widgetsService;
|
||||
_contentManager = contentManager;
|
||||
_layoutManager = layoutManager;
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
@@ -27,7 +30,8 @@ namespace Orchard.Widgets.Drivers {
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(WidgetPart widgetPart, dynamic shapeHelper) {
|
||||
widgetPart.AvailableZones = _widgetsService.GetZones();
|
||||
widgetPart.AvailableThemeZones = _widgetsService.GetZones();
|
||||
widgetPart.AvailableLayoutZones = _layoutManager.GetZones();
|
||||
widgetPart.AvailableLayers = _widgetsService.GetLayers();
|
||||
|
||||
var results = new List<DriverResult> {
|
||||
|
@@ -66,10 +66,16 @@ namespace Orchard.Widgets.Models {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The available page zones.
|
||||
/// The available theme zones.
|
||||
/// </summary>
|
||||
[HiddenInput(DisplayValue = false)]
|
||||
public IEnumerable<string> AvailableZones { get; set; }
|
||||
public IEnumerable<string> AvailableThemeZones { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The available layout zones.
|
||||
/// </summary>
|
||||
[HiddenInput(DisplayValue = false)]
|
||||
public IEnumerable<string> AvailableLayoutZones { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The available layers.
|
||||
|
@@ -7,7 +7,7 @@ OrchardVersion: 1.8
|
||||
Description: An implementation of widgets for Orchard.
|
||||
FeatureDescription: An implementation of widgets.
|
||||
Category: Widget
|
||||
Dependencies: Orchard.Scripting, Orchard.Themes
|
||||
Dependencies: Orchard.Scripting, Orchard.Themes, Orchard.Layouts
|
||||
Features:
|
||||
Orchard.Widgets.PageLayerHinting:
|
||||
Name: Page Layer Hinting
|
||||
|
@@ -70,6 +70,7 @@
|
||||
<Compile Include="Commands\WidgetCommands.cs" />
|
||||
<Compile Include="Controllers\AdminController.cs" />
|
||||
<Compile Include="ControlWrapper.cs" />
|
||||
<Compile Include="Drivers\ColumnElementDriver.cs" />
|
||||
<Compile Include="Drivers\LayerPartDriver.cs" />
|
||||
<Compile Include="Handlers\DisplayedContentItemHandler.cs" />
|
||||
<Compile Include="Handlers\LayerHintHandler.cs" />
|
||||
@@ -128,6 +129,10 @@
|
||||
<Name>Orchard.Framework</Name>
|
||||
<Private>True</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Layouts\Orchard.Layouts.csproj">
|
||||
<Project>{6bd8b2fa-f2e3-4ac8-a4c3-2925a653889a}</Project>
|
||||
<Name>Orchard.Layouts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Orchard.Scripting\Orchard.Scripting.csproj">
|
||||
<Project>{99002B65-86F7-415E-BF4A-381AA8AB9CCC}</Project>
|
||||
<Name>Orchard.Scripting</Name>
|
||||
|
@@ -15,7 +15,7 @@
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#widgets-layers-control label, #widgets-zones h2, #widgets-assistance h3 {
|
||||
#widgets-layers-control label, #widgets-zones h3, #widgets-assistance h3 {
|
||||
font-size: 1.077em;
|
||||
padding: 2px 2px;
|
||||
}
|
||||
@@ -63,12 +63,11 @@
|
||||
#widgets-zones-orphans-container p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
/* The number seems slightly meaningless. Leaving it out for now. * /
|
||||
#widgets-zones ol {
|
||||
list-style:decimal inside;
|
||||
}
|
||||
*/
|
||||
.widgets-listed ol {
|
||||
|
||||
#main .widgets-listed h2 {
|
||||
margin: 0.1em 0 0.6em;
|
||||
font-size: 1.1em;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#widgets-orphans ul {
|
||||
@@ -100,11 +99,11 @@ list-style:decimal inside;
|
||||
border-color: #487328;
|
||||
}
|
||||
|
||||
#widgets-available h2 {
|
||||
#widgets-available h3 {
|
||||
font-size: 1.231em;
|
||||
}
|
||||
|
||||
.widgets-listed h2, .widgets-listed li li, #widgets-layer-visibility li {
|
||||
.widgets-listed h3, .widgets-listed li li, #widgets-layer-visibility li {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<div id="widgets" class="group">
|
||||
@Display.WidgetFiltersControl(Layers: Model.Layers, CurrentLayer: Model.CurrentLayer, Cultures: Model.Cultures, CurrentCulture: Model.CurrentCulture)
|
||||
<div id="layout-widgets-placement">
|
||||
@Display.WidgetPlacement(Widgets: Model.Widgets, Zones: Model.Zones, OrphanZones: Model.OrphanZones, CurrentLayer: Model.CurrentLayer)
|
||||
@Display.WidgetPlacement(Widgets: Model.Widgets, ThemeZones: Model.ThemeZones, LayoutZones: Model.LayoutZones, OrphanZones: Model.OrphanZones, CurrentLayer: Model.CurrentLayer)
|
||||
</div>
|
||||
<div id="layout-widgets-assistance">
|
||||
<div id="widgets-assistance">
|
||||
|
@@ -1,8 +1,15 @@
|
||||
@model Orchard.Widgets.Models.WidgetPart
|
||||
@{
|
||||
var themeZonesGroup = Model.AvailableLayoutZones.Any() ? new SelectListGroup { Name = T("Theme Zones").Text } : default(SelectListGroup);
|
||||
var layoutZonesGroup = Model.AvailableLayoutZones.Any() ? new SelectListGroup { Name = T("Layout Zones").Text } : default(SelectListGroup); ;
|
||||
var themeZoneOptions = Model.AvailableThemeZones.Select(x => new SelectListItem { Text = x, Value = x, Selected = x == Model.Zone, Group = themeZonesGroup}).ToList();
|
||||
var layoutZoneOptions = Model.AvailableLayoutZones.Select(x => new SelectListItem { Text = x, Value = x, Selected = x == Model.Zone, Group = layoutZonesGroup}).ToList();
|
||||
var zoneOptions = themeZoneOptions.Concat(layoutZoneOptions);
|
||||
}
|
||||
<h2>@Model.TypeDefinition.DisplayName</h2>
|
||||
<fieldset>
|
||||
@Html.LabelFor(widget => widget.Zone, T("Zone"))
|
||||
@Html.DropDownListFor(widget => widget.Zone, new SelectList(Model.AvailableZones))
|
||||
@Html.DropDownListFor(widget => widget.Zone, zoneOptions)
|
||||
<span class="hint">@T("The Zone in the Layout where the Widget will be rendered.")</span>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
@@ -12,7 +19,7 @@
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
@Html.LabelFor(widget => widget.Position, T("Position"))
|
||||
@Html.TextBoxFor(widget => widget.Position, new { @class = "text small"})
|
||||
@Html.TextBoxFor(widget => widget.Position, new { @class = "text small" })
|
||||
<span class="hint">@T("The position of the Widget inside the Zone.")</span>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
|
@@ -8,15 +8,16 @@
|
||||
IEnumerable<string> zones = Model.Zones;
|
||||
var returnUrl = Request.RawUrl;
|
||||
}
|
||||
<h2>@Model.Title</h2>
|
||||
<ol>
|
||||
@foreach (string zone in zones) {
|
||||
int count = widgets.Where(w => w.Zone == zone).Count();
|
||||
var count = widgets.Count(w => w.Zone == zone);
|
||||
MvcHtmlString classAttr = null;
|
||||
if (count == 0) {
|
||||
classAttr = new MvcHtmlString("class=\"widgets-none\"");
|
||||
}
|
||||
<li @classAttr>
|
||||
<h2>@zone</h2>
|
||||
<h3>@zone</h3>
|
||||
<div class="widgets-actions">
|
||||
@Html.ActionLink(T("Add").Text, "ChooseWidget", new { layerId = Model.CurrentLayer.Id, zone, returnUrl }, new { @class = "button grey" })
|
||||
</div>
|
||||
@@ -68,42 +69,4 @@
|
||||
</ul>
|
||||
</li>
|
||||
}
|
||||
</ol>
|
||||
|
||||
@*
|
||||
@{
|
||||
Script.Require("ShapesBase");
|
||||
ContentPart contentPart = Model.ContentPart;
|
||||
}
|
||||
@if (contentPart.HasPublished()) {
|
||||
@Html.ItemDisplayLink(T("View").Text, (ContentItem)Model.ContentPart.ContentItem)
|
||||
@T(" | ")
|
||||
|
||||
if (contentPart.HasDraft()) {
|
||||
if (Authorizer.Authorize(Permissions.PublishContent, contentPart)) {
|
||||
@Html.Link(T("Publish Draft").Text, Url.Action("Publish", "Admin", new { area = "Contents", id = contentPart.ContentItem.Id, returnUrl = Request.ToUrlString() }), new { itemprop = "UnsafeUrl" })
|
||||
@T(" | ")
|
||||
|
||||
@Html.ActionLink(T("Preview").Text, "Preview", "Item", new { area = "Contents", id = ((ContentItem)Model.ContentPart.ContentItem).Id }, new { })
|
||||
@T(" | ")
|
||||
}
|
||||
}
|
||||
|
||||
if (Authorizer.Authorize(Permissions.PublishContent, contentPart)) {
|
||||
@Html.Link(T("Unpublish").Text, Url.Action("Unpublish", "Admin", new { area = "Contents", id = contentPart.ContentItem.Id, returnUrl = Request.ToUrlString() }), new { itemprop = "UnsafeUrl" })
|
||||
@T(" | ")
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (contentPart.HasDraft()) {
|
||||
@Html.ActionLink(T("Preview").Text, "Preview", "Item", new { area = "Contents", id = ((ContentItem)Model.ContentPart.ContentItem).Id }, new { })
|
||||
@T(" | ")
|
||||
}
|
||||
|
||||
if (Authorizer.Authorize(Permissions.PublishContent, contentPart)) {
|
||||
@Html.Link(T("Publish").Text, Url.Action("Publish", "Admin", new { area = "Contents", id = contentPart.ContentItem.Id, returnUrl = Request.ToUrlString() }), new { itemprop = "UnsafeUrl" })
|
||||
@T(" | ")
|
||||
}
|
||||
}
|
||||
|
||||
*@
|
||||
</ol>
|
@@ -1,23 +1,23 @@
|
||||
@using Orchard.Utility.Extensions;
|
||||
@using Orchard.Widgets.Models;
|
||||
@using Orchard.Widgets.Models
|
||||
@{
|
||||
Style.Require("WidgetsAdmin");
|
||||
IEnumerable<WidgetPart> widgets = Model.Widgets;
|
||||
IEnumerable<string> zones = Model.Zones;
|
||||
IEnumerable<string> themeZones = Model.ThemeZones;
|
||||
IEnumerable<string> layoutZones = Model.LayoutZones;
|
||||
IEnumerable<string> orphanZones = Model.OrphanZones;
|
||||
var returnUrl = Request.RawUrl;
|
||||
}
|
||||
<div id="widgets-placement">
|
||||
<div id="widgets-layers" class="widgets-container detail-view switchable">
|
||||
<div id="widgets-zones" class="widgets-listed">
|
||||
@Display.WidgetPlacement_Zones(Widgets: Model.Widgets, Zones: Model.Zones, CurrentLayer: Model.CurrentLayer)
|
||||
@Display.WidgetPlacement_Zones(Widgets: widgets, Zones: themeZones, CurrentLayer: Model.CurrentLayer, Title: T("Theme Zones"))
|
||||
@Display.WidgetPlacement_Zones(Widgets: widgets, Zones: layoutZones, CurrentLayer: Model.CurrentLayer, Title: T("Layout Zones"))
|
||||
</div>
|
||||
@if (orphanZones.Count() > 0) {
|
||||
@if (orphanZones.Any()) {
|
||||
<div id="widgets-zones-orphans-container">
|
||||
<h3>@T("Zones for other enabled themes.")</h3>
|
||||
<p>@T("Widgets in these zones will not appear anywhere when your currently active theme is applied. They might still appear in selectively applied (e.g. mobile) themes.")</p>
|
||||
<div id="widgets-zones-orphans" class="widgets-listed">
|
||||
@Display.WidgetPlacement_Zones(Widgets: Model.Widgets, Zones: Model.OrphanZones, CurrentLayer: Model.CurrentLayer)
|
||||
@Display.WidgetPlacement_Zones(Widgets: widgets, Zones: Model.OrphanZones, CurrentLayer: Model.CurrentLayer)
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
Reference in New Issue
Block a user