mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-12-03 20:13:52 +08:00
Roughing in Containers module
Container/containable editor templates appear Container id settable via drop list ContainerPathConstraint of higher priority providing list view --HG-- branch : dev
This commit is contained in:
@@ -1,11 +1,57 @@
|
|||||||
using System.Web.Mvc;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.ContentManagement.Aspects;
|
||||||
|
using Orchard.Core.Common.Models;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
|
using Orchard.DisplayManagement;
|
||||||
using Orchard.Themes;
|
using Orchard.Themes;
|
||||||
|
|
||||||
namespace Orchard.Core.Containers.Controllers {
|
namespace Orchard.Core.Containers.Controllers {
|
||||||
public class ItemController: Controller {
|
public class ItemController : Controller {
|
||||||
|
private readonly IContentManager _contentManager;
|
||||||
|
private readonly IContainersPathConstraint _containersPathConstraint;
|
||||||
|
|
||||||
|
public ItemController(IContentManager contentManager, IContainersPathConstraint containersPathConstraint, IShapeFactory shapeFactory) {
|
||||||
|
_contentManager = contentManager;
|
||||||
|
_containersPathConstraint = containersPathConstraint;
|
||||||
|
New = shapeFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic New { get; set; }
|
||||||
|
|
||||||
[Themed]
|
[Themed]
|
||||||
public ActionResult Display(string path, int? page) {
|
public ActionResult Display(string path, int? page) {
|
||||||
return View();
|
var matchedPath = _containersPathConstraint.FindPath(path);
|
||||||
|
if (string.IsNullOrEmpty(matchedPath)) {
|
||||||
|
throw new ApplicationException("404 - should not have passed path constraint");
|
||||||
|
}
|
||||||
|
|
||||||
|
var hits = _contentManager
|
||||||
|
.Query<RoutePart, RoutePartRecord>(VersionOptions.Published)
|
||||||
|
.Where(r => r.Path == matchedPath)
|
||||||
|
.Slice(0, 2);
|
||||||
|
|
||||||
|
if (hits.Count() == 0) {
|
||||||
|
throw new ApplicationException("404 - should not have passed path constraint");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hits.Count() != 1) {
|
||||||
|
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 itemDisplays = items.Select(item => _contentManager.BuildDisplay(item, "Summary"));
|
||||||
|
var list = New.List();
|
||||||
|
list.AddRange(itemDisplays);
|
||||||
|
|
||||||
|
return View(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,60 @@
|
|||||||
using Orchard.ContentManagement.Drivers;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.ContentManagement.Aspects;
|
||||||
|
using Orchard.ContentManagement.Drivers;
|
||||||
using Orchard.Core.Containers.Models;
|
using Orchard.Core.Containers.Models;
|
||||||
|
using Orchard.Core.Containers.ViewModels;
|
||||||
|
using Orchard.Localization;
|
||||||
|
|
||||||
namespace Orchard.Core.Containers.Drivers {
|
namespace Orchard.Core.Containers.Drivers {
|
||||||
public class ContainablePartDriver : ContentPartDriver<ContainablePart> {
|
public class ContainablePartDriver : ContentPartDriver<ContainablePart> {
|
||||||
|
private readonly IContentManager _contentManager;
|
||||||
|
|
||||||
|
public ContainablePartDriver(IContentManager contentManager) {
|
||||||
|
_contentManager = contentManager;
|
||||||
|
T = NullLocalizer.Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Localizer T { get; set; }
|
||||||
|
|
||||||
|
protected override DriverResult Editor(ContainablePart part, dynamic shapeHelper) {
|
||||||
|
return Editor(part, null, shapeHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override DriverResult Editor(ContainablePart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||||
|
return ContentShape(
|
||||||
|
"Parts_Containable_Edit",
|
||||||
|
() => {
|
||||||
|
var commonPart = part.As<ICommonPart>();
|
||||||
|
|
||||||
|
var model = new ContainableViewModel();
|
||||||
|
if (commonPart.Container != null) {
|
||||||
|
model.ContainerId = commonPart.Container.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updater != null) {
|
||||||
|
var oldContainerId = model.ContainerId;
|
||||||
|
updater.TryUpdateModel(model, "Containable", null, null);
|
||||||
|
if (oldContainerId != model.ContainerId) {
|
||||||
|
commonPart.Container = _contentManager.Get(model.ContainerId, VersionOptions.Latest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var containers = _contentManager.Query<ContainerPart, ContainerPartRecord>(VersionOptions.Latest).List();
|
||||||
|
var listItems = new[] { new SelectListItem { Text = T("(None)").Text, Value = "0" } }
|
||||||
|
.Concat(containers.Select(x => new SelectListItem {
|
||||||
|
Value = Convert.ToString(x.Id),
|
||||||
|
Text = x.ContentItem.TypeDefinition.DisplayName + ": " + x.As<IRoutableAspect>().Title,
|
||||||
|
Selected = x.Id == model.ContainerId,
|
||||||
|
}))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
model.AvailableContainers = new SelectList(listItems, "Value", "Text", model.ContainerId);
|
||||||
|
|
||||||
|
return shapeHelper.EditorTemplate(TemplateName: "Containable", Model: model, Prefix: "Containable");
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,28 @@
|
|||||||
using Orchard.ContentManagement.Drivers;
|
using Orchard.ContentManagement.Drivers;
|
||||||
|
using Orchard.ContentManagement.Handlers;
|
||||||
using Orchard.Core.Containers.Models;
|
using Orchard.Core.Containers.Models;
|
||||||
|
using Orchard.Data;
|
||||||
|
|
||||||
namespace Orchard.Core.Containers.Drivers {
|
namespace Orchard.Core.Containers.Drivers {
|
||||||
public class ContainerPartDriver : ContentPartDriver<ContainerPart>{
|
public class ContainerPartDriver : ContentPartDriver<ContainerPart> {
|
||||||
|
protected override DriverResult Editor(ContainerPart part, dynamic shapeHelper) {
|
||||||
|
return Editor(part, null, shapeHelper);
|
||||||
|
}
|
||||||
|
protected override DriverResult Editor(ContainerPart part, ContentManagement.IUpdateModel updater, dynamic shapeHelper) {
|
||||||
|
return ContentShape(
|
||||||
|
"Parts_Container_Edit",
|
||||||
|
() => {
|
||||||
|
if (updater != null)
|
||||||
|
updater.TryUpdateModel(part, "Container", null, null);
|
||||||
|
|
||||||
|
return shapeHelper.EditorTemplate(TemplateName: "Container", Model: part, Prefix: "Container");
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public class ContainerPartHandler : ContentHandler {
|
||||||
|
public ContainerPartHandler(IRepository<ContainerPartRecord> repository) {
|
||||||
|
Filters.Add(StorageFilter.For(repository));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ namespace Orchard.Core.Containers.Models {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class ContainerPartRecord : ContentPartRecord {
|
public class ContainerPartRecord : ContentPartRecord {
|
||||||
public virtual bool Paginated { get; set; }
|
public virtual int Paginated { get; set; }
|
||||||
public virtual int PageSize { get; set; }
|
public virtual int PageSize { get; set; }
|
||||||
public virtual string OrderByProperty { get; set; }
|
public virtual string OrderByProperty { get; set; }
|
||||||
public virtual OrderByDirection OrderByDirection { get; set; }
|
public virtual int OrderByDirection { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum OrderByDirection {
|
public enum OrderByDirection {
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ Description: The common module introduces container and containable behaviors fo
|
|||||||
Features:
|
Features:
|
||||||
Containers:
|
Containers:
|
||||||
Description: Container content parts.
|
Description: Container content parts.
|
||||||
Dependencies: Settings
|
Dependencies: Contents, Routable
|
||||||
Category: Content
|
Category: Content
|
||||||
|
|||||||
4
src/Orchard.Web/Core/Containers/Placement.info
Normal file
4
src/Orchard.Web/Core/Containers/Placement.info
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<Placement>
|
||||||
|
<Place Parts_Containable_Edit="Content:before.3"/>
|
||||||
|
<Place Parts_Container_Edit="Content:5"/>
|
||||||
|
</Placement>
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.Core.Containers.Models;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
|
using Orchard.Environment;
|
||||||
|
using Orchard.Tasks;
|
||||||
|
|
||||||
|
namespace Orchard.Core.Containers.Services {
|
||||||
|
public class ContainersPathConstraintUpdater : IOrchardShellEvents, IBackgroundTask {
|
||||||
|
private readonly IContainersPathConstraint _containersPathConstraint;
|
||||||
|
private readonly IContentManager _contentManager;
|
||||||
|
|
||||||
|
public ContainersPathConstraintUpdater(IContainersPathConstraint containersPathConstraint, IContentManager contentManager) {
|
||||||
|
_containersPathConstraint = containersPathConstraint;
|
||||||
|
_contentManager = contentManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOrchardShellEvents.Activated() {
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOrchardShellEvents.Terminating() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void IBackgroundTask.Sweep() {
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Refresh() {
|
||||||
|
var routeParts = _contentManager.Query<RoutePart, RoutePartRecord>().Join<ContainerPartRecord>().List();
|
||||||
|
_containersPathConstraint.SetPaths(routeParts.Select(x=>x.Path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
|
||||||
|
namespace Orchard.Core.Containers.ViewModels {
|
||||||
|
public class ContainableViewModel {
|
||||||
|
public int ContainerId { get; set; }
|
||||||
|
public SelectList AvailableContainers { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
@model Orchard.Core.Containers.ViewModels.ContainableViewModel
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
@Html.LabelFor(m => m.ContainerId, T("Add to"))
|
||||||
|
@Html.DropDownListFor(m => m.ContainerId, Model.AvailableContainers)
|
||||||
|
</fieldset>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
@model Orchard.Core.Containers.Models.ContainerPart
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
@Html.LabelFor(m => m.Record.Paginated, T("Paginated"))
|
||||||
|
@Html.TextBoxFor(m => m.Record.Paginated)
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
@Html.LabelFor(m => m.Record.PageSize, T("PageSize"))
|
||||||
|
@Html.TextBoxFor(m => m.Record.PageSize)
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
@Html.LabelFor(m => m.Record.OrderByProperty, T("OrderByProperty"))
|
||||||
|
@Html.TextBoxFor(m => m.Record.OrderByProperty)
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
@Html.LabelFor(m => m.Record.OrderByDirection, T("OrderByDirection"))
|
||||||
|
@Html.TextBoxFor(m => m.Record.OrderByDirection)
|
||||||
|
</fieldset>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
@Display(Model)
|
||||||
@@ -80,6 +80,8 @@
|
|||||||
<Compile Include="Common\Shapes.cs" />
|
<Compile Include="Common\Shapes.cs" />
|
||||||
<Compile Include="Common\Fields\TextField.cs" />
|
<Compile Include="Common\Fields\TextField.cs" />
|
||||||
<Compile Include="Containers\Routes.cs" />
|
<Compile Include="Containers\Routes.cs" />
|
||||||
|
<Compile Include="Containers\Services\ContainersPathConstraintUpdater.cs" />
|
||||||
|
<Compile Include="Containers\ViewModels\ContainableViewModel.cs" />
|
||||||
<Compile Include="Contents\Security\AuthorizationEventHandler.cs" />
|
<Compile Include="Contents\Security\AuthorizationEventHandler.cs" />
|
||||||
<Compile Include="Common\Services\BbcodeFilter.cs" />
|
<Compile Include="Common\Services\BbcodeFilter.cs" />
|
||||||
<Compile Include="Common\Services\ICommonService.cs" />
|
<Compile Include="Common\Services\ICommonService.cs" />
|
||||||
@@ -387,6 +389,10 @@
|
|||||||
<Content Include="Settings\Styles\Web.config">
|
<Content Include="Settings\Styles\Web.config">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="Containers\Placement.info" />
|
||||||
|
<Content Include="Containers\Views\EditorTemplates\Containable.cshtml" />
|
||||||
|
<Content Include="Containers\Views\EditorTemplates\Container.cshtml" />
|
||||||
|
<Content Include="Containers\Views\Item\Display.cshtml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace Orchard.Lists {
|
|||||||
.WithPart("CommonPart")
|
.WithPart("CommonPart")
|
||||||
.WithPart("RoutePart")
|
.WithPart("RoutePart")
|
||||||
.WithPart("ContainerPart")
|
.WithPart("ContainerPart")
|
||||||
|
.WithPart("MenuPart")
|
||||||
.Creatable());
|
.Creatable());
|
||||||
|
|
||||||
//ContentDefinitionManager.AlterTypeDefinition("ListWidget",
|
//ContentDefinitionManager.AlterTypeDefinition("ListWidget",
|
||||||
|
|||||||
Reference in New Issue
Block a user