Incremental work on blending layouts, zones and widgets.

This commit is contained in:
Sipke Schoorstra
2015-04-03 17:29:47 +02:00
parent 765c265977
commit 804b4bbc7b
23 changed files with 222 additions and 138 deletions

View File

@@ -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> {}
}

View File

@@ -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); }
}
}
}

View File

@@ -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));

View File

@@ -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

View File

@@ -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 = {}));

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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);

View File

@@ -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()

View File

@@ -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>

View File

@@ -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>

View File

@@ -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())

View File

@@ -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);
}
}
}
}

View File

@@ -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> {

View File

@@ -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.

View File

@@ -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

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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">

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>
}