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:
Nathan Heskew
2010-11-11 16:15:49 -08:00
parent fb4ab81df5
commit ce128483bc
20 changed files with 199 additions and 73 deletions

View File

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

View File

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

View File

@@ -13,6 +13,13 @@ namespace Orchard.Core.Containers {
.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());

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,6 @@
namespace Orchard.Core.Containers.Models {
public enum OrderByDirection {
Ascending,
Descending,
}
}

View File

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

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Builders;

View File

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

View File

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

View File

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

View File

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

View File

@@ -1 +1,2 @@
@Display(Model)
@Display(Model.ContentItems)
@Display(Model.Pager)

View File

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

View File

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

View File

@@ -81,7 +81,6 @@ namespace Orchard.Setup.Services {
"Localization",
"Routable",
"Settings",
"XmlRpc",
"Messaging",
"Orchard.Users",
"Orchard.Roles",

View File

@@ -45,6 +45,7 @@ namespace Orchard.Widgets.Services {
.Where(x => x.ExtensionType == "Theme")
.SelectMany(x => x.Zones.Split(','))
.Distinct()
.Select(x => x.Trim())
.ToArray();
}

View File

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

View File

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