mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-09-23 21:13:35 +08:00
Bunch of work for containers.
- Ordering and paging on the container mostly hooked up. Paging needs to respect item settings. - Widget settings looking good but not yet functioning. Also need to add filtering. - Custom part not yet in place for custom ordering/filtering. --HG-- branch : dev
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Containers.Models;
|
||||
using Orchard.Core.Routable.Models;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Themes;
|
||||
@@ -17,10 +17,10 @@ namespace Orchard.Core.Containers.Controllers {
|
||||
public ItemController(IContentManager contentManager, IContainersPathConstraint containersPathConstraint, IShapeFactory shapeFactory) {
|
||||
_contentManager = contentManager;
|
||||
_containersPathConstraint = containersPathConstraint;
|
||||
New = shapeFactory;
|
||||
Shape = shapeFactory;
|
||||
}
|
||||
|
||||
dynamic New { get; set; }
|
||||
dynamic Shape { get; set; }
|
||||
|
||||
[Themed]
|
||||
public ActionResult Display(string path, Pager pager) {
|
||||
@@ -42,17 +42,42 @@ namespace Orchard.Core.Containers.Controllers {
|
||||
throw new ApplicationException("Ambiguous content");
|
||||
}
|
||||
|
||||
var containerId = hits.Single().Id;
|
||||
var items = _contentManager
|
||||
.Query<ContentPart<CommonPartRecord>, CommonPartRecord>(VersionOptions.Published)
|
||||
.Where(x => x.Container.Id == containerId)
|
||||
.List();
|
||||
var container = _contentManager.Get(hits.Single().Id);
|
||||
IContentQuery<ContentItem> query = _contentManager
|
||||
.Query(VersionOptions.Published)
|
||||
.Join<CommonPartRecord>().Where(cr => cr.Container.Id == container.Id);
|
||||
|
||||
var itemDisplays = items.Select(item => _contentManager.BuildDisplay(item, "Summary"));
|
||||
var list = New.List();
|
||||
list.AddRange(itemDisplays);
|
||||
var descendingOrder = container.As<ContainerPart>().Record.OrderByDirection == (int) OrderByDirection.Descending;
|
||||
//todo: (heskew) order by custom part properties
|
||||
switch (container.As<ContainerPart>().Record.OrderByProperty) {
|
||||
case "RoutePart.Title":
|
||||
query = descendingOrder
|
||||
? query.OrderByDescending<RoutePartRecord, string>(record => record.Title)
|
||||
: query.OrderBy<RoutePartRecord, string>(record => record.Title);
|
||||
break;
|
||||
case "RoutePart.Slug":
|
||||
query = descendingOrder
|
||||
? query.OrderByDescending<RoutePartRecord, string>(record => record.Slug)
|
||||
: query.OrderBy<RoutePartRecord, string>(record => record.Slug);
|
||||
break;
|
||||
default: // "CommonPart.PublishedUtc"
|
||||
query = descendingOrder
|
||||
? query.OrderByDescending<CommonPartRecord, DateTime?>(record => record.PublishedUtc)
|
||||
: query.OrderBy<CommonPartRecord, DateTime?>(record => record.PublishedUtc);
|
||||
break;
|
||||
}
|
||||
|
||||
return View(list);
|
||||
var pagerShape = Shape.Pager(pager).TotalItemCount(query.Count());
|
||||
var pageOfItems = query.Slice(pager.GetStartIndex(), pager.PageSize).ToList();
|
||||
|
||||
var list = Shape.List();
|
||||
list.AddRange(pageOfItems.Select(item => _contentManager.BuildDisplay(item, "Summary")));
|
||||
|
||||
var viewModel = Shape.ViewModel()
|
||||
.ContentItems(list)
|
||||
.Pager(pagerShape);
|
||||
|
||||
return View(viewModel);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Containers.Models;
|
||||
using Orchard.Data;
|
||||
using Orchard.Localization;
|
||||
|
||||
namespace Orchard.Core.Containers.Drivers {
|
||||
public class ContainerWidgetPartDriver : ContentPartDriver<ContainerWidgetPart> {
|
||||
private readonly IContentManager _contentManager;
|
||||
|
||||
public ContainerWidgetPartDriver(IContentManager contentManager) {
|
||||
_contentManager = contentManager;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
protected override DriverResult Editor(ContainerWidgetPart part, dynamic shapeHelper) {
|
||||
return Editor(part, null, shapeHelper);
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(ContainerWidgetPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
return ContentShape(
|
||||
"Parts_ContainerWidget_Edit",
|
||||
() => {
|
||||
if (updater != null)
|
||||
updater.TryUpdateModel(part, "ContainerSelector", null, null);
|
||||
|
||||
var containers = _contentManager.Query<ContainerPart, ContainerPartRecord>(VersionOptions.Latest).List();
|
||||
|
||||
var listItems = containers.Count() < 1
|
||||
? new[] {new SelectListItem {Text = T("(None - create container enabled items first)").Text, Value = "0"}}
|
||||
: containers.Select(x => new SelectListItem {
|
||||
Value = Convert.ToString(x.Id),
|
||||
Text = x.ContentItem.TypeDefinition.DisplayName + ": " + x.As<IRoutableAspect>().Title,
|
||||
Selected = x.Id == part.Record.ContainerId,
|
||||
});
|
||||
|
||||
part.AvailableContainers = new SelectList(listItems, "Value", "Text", part.Record.ContainerId);
|
||||
|
||||
return shapeHelper.EditorTemplate(TemplateName: "ContainerWidget", Model: part, Prefix: "ContainerWidget");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class ContainerWidgetPartHandler : ContentHandler {
|
||||
public ContainerWidgetPartHandler(IRepository<ContainerWidgetPartRecord> repository, IOrchardServices orchardServices) {
|
||||
Filters.Add(StorageFilter.For(repository));
|
||||
OnInitializing<ContainerWidgetPart>((context, part) => {
|
||||
part.Record.ContainerId = 0;
|
||||
part.Record.PageSize = 5;
|
||||
part.Record.OrderByProperty = part.Is<CommonPart>() ? "CommonPart.PublishedUtc" : "";
|
||||
part.Record.OrderByDirection = (int)OrderByDirection.Descending;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -6,12 +6,19 @@ namespace Orchard.Core.Containers {
|
||||
public class Migrations : DataMigrationImpl {
|
||||
public int Create() {
|
||||
SchemaBuilder.CreateTable("ContainerPartRecord",
|
||||
table => table
|
||||
.ContentPartRecord()
|
||||
.Column<bool>("Paginated")
|
||||
.Column<int>("PageSize")
|
||||
.Column<string>("OrderByProperty")
|
||||
.Column<int>("OrderByDirection"));
|
||||
table => table
|
||||
.ContentPartRecord()
|
||||
.Column<bool>("Paginated")
|
||||
.Column<int>("PageSize")
|
||||
.Column<string>("OrderByProperty")
|
||||
.Column<int>("OrderByDirection"));
|
||||
|
||||
ContentDefinitionManager.AlterTypeDefinition("ContainerWidget",
|
||||
cfg => cfg
|
||||
.WithPart("CommonPart")
|
||||
.WithPart("WidgetPart")
|
||||
.WithPart("ContainerWidgetPart")
|
||||
.WithSetting("Stereotype", "Widget"));
|
||||
|
||||
ContentDefinitionManager.AlterPartDefinition("ContainerPart", builder => builder.Attachable());
|
||||
ContentDefinitionManager.AlterPartDefinition("ContainablePart", builder => builder.Attachable());
|
||||
|
@@ -11,9 +11,4 @@ namespace Orchard.Core.Containers.Models {
|
||||
public virtual string OrderByProperty { get; set; }
|
||||
public virtual int OrderByDirection { get; set; }
|
||||
}
|
||||
|
||||
public enum OrderByDirection {
|
||||
Ascending,
|
||||
Descending,
|
||||
}
|
||||
}
|
||||
|
@@ -1,15 +0,0 @@
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Records;
|
||||
|
||||
namespace Orchard.Core.Containers.Models {
|
||||
public class ContainerSettingsPart : ContentPart<ContainerSettingsPartRecord> {
|
||||
}
|
||||
|
||||
public class ContainerSettingsPartRecord : ContentPartRecord {
|
||||
private int _defaultPageSize = 10;
|
||||
public virtual int DefaultPageSize {
|
||||
get { return _defaultPageSize; }
|
||||
set { _defaultPageSize = value; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Records;
|
||||
|
||||
namespace Orchard.Core.Containers.Models {
|
||||
public class ContainerWidgetPart : ContentPart<ContainerWidgetPartRecord> {
|
||||
public SelectList AvailableContainers { get; set; }
|
||||
}
|
||||
|
||||
public class ContainerWidgetPartRecord : ContentPartRecord {
|
||||
public virtual int ContainerId { get; set; }
|
||||
public virtual int PageSize { get; set; }
|
||||
public virtual string OrderByProperty { get; set; }
|
||||
public virtual int OrderByDirection { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
namespace Orchard.Core.Containers.Models {
|
||||
public enum OrderByDirection {
|
||||
Ascending,
|
||||
Descending,
|
||||
}
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
<Placement>
|
||||
<Place Parts_Containable_Edit="Content:before.3"/>
|
||||
<Place Parts_Container_Edit="Content:5"/>
|
||||
<Place Parts_ContainerWidget_Edit="Content:5"/>
|
||||
<Place Parts_Container_SiteSettings="Content:10"/>
|
||||
</Placement>
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
|
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Orchard.Core.Containers.ViewModels {
|
||||
public class ContainableViewModel {
|
||||
|
@@ -1,5 +1,4 @@
|
||||
@model Orchard.Core.Containers.ViewModels.ContainableViewModel
|
||||
|
||||
<fieldset>
|
||||
@Html.LabelFor(m => m.ContainerId, T("Add to"))
|
||||
@Html.DropDownListFor(m => m.ContainerId, Model.AvailableContainers)
|
||||
|
@@ -1,21 +1,27 @@
|
||||
@model Orchard.Core.Containers.Models.ContainerPart
|
||||
@using Orchard.Core.Containers.Models;
|
||||
<fieldset class="with-checkbox">
|
||||
<span>
|
||||
@Html.LabelFor(m => m.Record.PageSize, T("Page Size"))
|
||||
@Html.EditorFor(m => m.Record.PageSize)
|
||||
</span>
|
||||
<span class="checkbox-and-label">
|
||||
@Html.CheckBoxFor(m => m.Record.Paginated)
|
||||
<label for="@Html.FieldIdFor( m => m.Record.Paginated)" class="forcheckbox">@T("Show paging controls")</label>
|
||||
</span>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
@Html.LabelFor(m => m.Record.OrderByProperty, T("Order By"))
|
||||
@Html.TextBoxFor(m => m.Record.OrderByProperty, new { @class = "textMedium" })
|
||||
<select id="@Html.FieldIdFor( m => m.Record.OrderByDirection)" name="@Html.FieldIdFor( m => m.Record.OrderByDirection)">
|
||||
@Html.LabelFor(m => m.Record.OrderByProperty, T("Order by"))
|
||||
<select id="@Html.FieldIdFor(m => m.Record.OrderByProperty)" name="@Html.FieldNameFor(m => m.Record.OrderByProperty)">
|
||||
@Html.SelectOption(Model.Record.OrderByProperty, "CommonPart.PublishedUtc", T("Date Published").Text)
|
||||
@Html.SelectOption(Model.Record.OrderByProperty, "RoutePart.Title", T("Title").Text)
|
||||
@Html.SelectOption(Model.Record.OrderByProperty, "RoutePart.Slug", T("Slug").Text)
|
||||
@Html.SelectOption(Model.Record.OrderByProperty, "ContainerCustomPart.Custom1", T("Custom 1").Text)
|
||||
@Html.SelectOption(Model.Record.OrderByProperty, "ContainerCustomPart.Custom2", T("Custom 2").Text)
|
||||
@Html.SelectOption(Model.Record.OrderByProperty, "ContainerCustomPart.Custom3", T("Custom 3").Text)
|
||||
</select>
|
||||
<select id="@Html.FieldIdFor(m => m.Record.OrderByDirection)" name="@Html.FieldNameFor(m => m.Record.OrderByDirection)">
|
||||
@Html.SelectOption(Model.Record.OrderByDirection, (int)OrderByDirection.Ascending, T("Ascending").Text)
|
||||
@Html.SelectOption(Model.Record.OrderByDirection, (int)OrderByDirection.Descending, T("Descending").Text)
|
||||
</select>
|
||||
<span class="hint">Currently, only ordering by a content part property is supported (e.g. CommonPart.PublishedUtc).</span>
|
||||
</fieldset>
|
||||
<fieldset class="with-checkbox">
|
||||
<span>
|
||||
@Html.LabelFor(m => m.Record.PageSize, T("Page size"))
|
||||
@Html.TextBoxFor(m => m.Record.PageSize, new { @class = "text text-small" })
|
||||
</span>
|
||||
<span class="checkbox-and-label">
|
||||
@Html.CheckBoxFor(m => m.Record.Paginated)
|
||||
<label for="@Html.FieldIdFor(m => m.Record.Paginated)" class="forcheckbox">@T("Show paging controls")</label>
|
||||
</span>
|
||||
</fieldset>
|
@@ -0,0 +1,27 @@
|
||||
@model Orchard.Core.Containers.Models.ContainerWidgetPart
|
||||
@using Orchard.Core.Containers.Models;
|
||||
<fieldset>
|
||||
@Html.LabelFor(m => m.Record.ContainerId, T("Show items from"))
|
||||
@Html.DropDownListFor(m => m.Record.ContainerId, Model.AvailableContainers)
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
@Html.LabelFor(m => m.Record.OrderByProperty, T("Order by"))
|
||||
<select id="@Html.FieldIdFor(m => m.Record.OrderByProperty)" name="@Html.FieldNameFor(m => m.Record.OrderByProperty)">
|
||||
@Html.SelectOption(Model.Record.OrderByProperty, "CommonPart.PublishedUtc", T("Date Published").Text)
|
||||
@Html.SelectOption(Model.Record.OrderByProperty, "RoutePart.Title", T("Title").Text)
|
||||
@Html.SelectOption(Model.Record.OrderByProperty, "RoutePart.Slug", T("Slug").Text)
|
||||
@Html.SelectOption(Model.Record.OrderByProperty, "ContainerCustomPart.Custom1", T("Custom 1").Text)
|
||||
@Html.SelectOption(Model.Record.OrderByProperty, "ContainerCustomPart.Custom2", T("Custom 2").Text)
|
||||
@Html.SelectOption(Model.Record.OrderByProperty, "ContainerCustomPart.Custom3", T("Custom 3").Text)
|
||||
</select>
|
||||
<select id="@Html.FieldIdFor(m => m.Record.OrderByDirection)" name="@Html.FieldNameFor(m => m.Record.OrderByDirection)">
|
||||
@Html.SelectOption(Model.Record.OrderByDirection, (int)OrderByDirection.Ascending, T("Ascending").Text)
|
||||
@Html.SelectOption(Model.Record.OrderByDirection, (int)OrderByDirection.Descending, T("Descending").Text)
|
||||
</select>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<span>
|
||||
@Html.LabelFor(m => m.Record.PageSize, T("Maximum number of items to display"))
|
||||
@Html.TextBoxFor(m => m.Record.PageSize, new { @class = "text text-small" })
|
||||
</span>
|
||||
</fieldset>
|
@@ -1 +1,2 @@
|
||||
@Display(Model)
|
||||
@Display(Model.ContentItems)
|
||||
@Display(Model.Pager)
|
@@ -78,12 +78,14 @@
|
||||
<Compile Include="Common\Drivers\CommonPartDriver.cs" />
|
||||
<Compile Include="Common\Drivers\TextFieldDriver.cs" />
|
||||
<Compile Include="Containers\ContainersPathConstraint.cs" />
|
||||
<Compile Include="Containers\Drivers\ContainerWidgetPartDriver.cs" />
|
||||
<Compile Include="Containers\Migrations.cs" />
|
||||
<Compile Include="Containers\Models\ContainerSettingsPart.cs" />
|
||||
<Compile Include="Containers\Models\ContainablePart.cs" />
|
||||
<Compile Include="Containers\Models\ContainerPart.cs" />
|
||||
<Compile Include="Common\Shapes.cs" />
|
||||
<Compile Include="Common\Fields\TextField.cs" />
|
||||
<Compile Include="Containers\Models\ContainerWidgetPart.cs" />
|
||||
<Compile Include="Containers\Models\OrderByDirection.cs" />
|
||||
<Compile Include="Containers\Routes.cs" />
|
||||
<Compile Include="Containers\Services\ContainersPathConstraintUpdater.cs" />
|
||||
<Compile Include="Containers\Settings\ContainerSettings.cs" />
|
||||
@@ -398,11 +400,12 @@
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<Content Include="Containers\Placement.info" />
|
||||
<Content Include="Containers\Views\EditorTemplates\Containable.cshtml" />
|
||||
<Content Include="Containers\Views\EditorTemplates\ContainerWidget.cshtml" />
|
||||
<Content Include="Containers\Views\EditorTemplates\Container.cshtml" />
|
||||
<Content Include="Containers\Views\Item\Display.cshtml" />
|
||||
<Content Include="Containers\Views\DefinitionTemplates\ContainerPartSettings.cshtml" />
|
||||
<Content Include="Containers\Views\DefinitionTemplates\ContainerTypePartSettings.cshtml" />
|
||||
<Content Include="Containers\Views\EditorTemplates\Containable.cshtml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||
|
@@ -13,13 +13,6 @@ namespace Orchard.Lists {
|
||||
.WithPart("MenuPart")
|
||||
.Creatable());
|
||||
|
||||
ContentDefinitionManager.AlterTypeDefinition("ListWidget",
|
||||
cfg => cfg
|
||||
.WithPart("CommonPart")
|
||||
.WithPart("WidgetPart")
|
||||
.WithPart("ContainerPart")
|
||||
.WithSetting("Stereotype", "Widget"));
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@@ -81,7 +81,6 @@ namespace Orchard.Setup.Services {
|
||||
"Localization",
|
||||
"Routable",
|
||||
"Settings",
|
||||
"XmlRpc",
|
||||
"Messaging",
|
||||
"Orchard.Users",
|
||||
"Orchard.Roles",
|
||||
|
@@ -45,6 +45,7 @@ namespace Orchard.Widgets.Services {
|
||||
.Where(x => x.ExtensionType == "Theme")
|
||||
.SelectMany(x => x.Zones.Split(','))
|
||||
.Distinct()
|
||||
.Select(x => x.Trim())
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
|
@@ -486,6 +486,9 @@ select, textarea, input.text, input.textMedium, input.text-box {
|
||||
input.text, input.textMedium, input.text-box {
|
||||
line-height:1.2em;
|
||||
}
|
||||
input.text-small {
|
||||
width:4em;
|
||||
}
|
||||
input.textMedium {
|
||||
width:26em;
|
||||
}
|
||||
|
@@ -34,7 +34,8 @@ namespace Orchard.Environment.Features {
|
||||
}
|
||||
|
||||
public IEnumerable<FeatureDescriptor> GetEnabledFeatures() {
|
||||
throw new NotImplementedException();
|
||||
var currentShellDescriptor = _shellDescriptorManager.GetShellDescriptor();
|
||||
return _extensionManager.EnabledFeatures(currentShellDescriptor);
|
||||
}
|
||||
|
||||
public void EnableFeatures(IEnumerable<string> featureNames) {
|
||||
|
Reference in New Issue
Block a user