mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Fix container routing
--HG-- branch : autoroute
This commit is contained in:
@@ -1,45 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Orchard.Core.Containers {
|
||||
public interface IContainersPathConstraint : IRouteConstraint, ISingletonDependency {
|
||||
void SetPaths(IEnumerable<string> paths);
|
||||
string FindPath(string path);
|
||||
void AddPath(string path);
|
||||
}
|
||||
|
||||
public class ContainersPathConstraint : IContainersPathConstraint {
|
||||
private IDictionary<string, string> _paths = new Dictionary<string, string>();
|
||||
|
||||
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) {
|
||||
if (routeDirection == RouteDirection.UrlGeneration)
|
||||
return true;
|
||||
|
||||
object value;
|
||||
if (values.TryGetValue(parameterName, out value)) {
|
||||
var parameterValue = Convert.ToString(value);
|
||||
return _paths.ContainsKey(parameterValue);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetPaths(IEnumerable<string> paths) {
|
||||
// Note: this does not need to be synchronized as long as the dictionary itself is treated as immutable.
|
||||
// do not add or remove to the dictionary instance once created. recreate and reassign instead.
|
||||
_paths = paths.Distinct().ToDictionary(path => path, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public string FindPath(string path) {
|
||||
string actual;
|
||||
return _paths.TryGetValue(path, out actual) ? actual : path;
|
||||
}
|
||||
|
||||
public void AddPath(string path) {
|
||||
SetPaths(_paths.Keys.Concat(new[] { path }));
|
||||
}
|
||||
}
|
||||
}
|
@@ -13,56 +13,44 @@ using Orchard.Mvc;
|
||||
using Orchard.Themes;
|
||||
using Orchard.UI.Navigation;
|
||||
using Orchard.Settings;
|
||||
using Orchard.Localization;
|
||||
|
||||
namespace Orchard.Core.Containers.Controllers {
|
||||
|
||||
public class ItemController : Controller {
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly IContainersPathConstraint _containersPathConstraint;
|
||||
private readonly ISiteService _siteService;
|
||||
private readonly IFeedManager _feedManager;
|
||||
|
||||
public ItemController(
|
||||
IContentManager contentManager,
|
||||
IContainersPathConstraint containersPathConstraint,
|
||||
IShapeFactory shapeFactory,
|
||||
ISiteService siteService,
|
||||
IFeedManager feedManager) {
|
||||
|
||||
_contentManager = contentManager;
|
||||
_containersPathConstraint = containersPathConstraint;
|
||||
_siteService = siteService;
|
||||
_feedManager = feedManager;
|
||||
Shape = shapeFactory;
|
||||
T = NullLocalizer.Instance;
|
||||
}
|
||||
|
||||
dynamic Shape { get; set; }
|
||||
|
||||
public Localizer T { get; set; }
|
||||
[Themed]
|
||||
public ActionResult Display(string path, PagerParameters pagerParameters) {
|
||||
var matchedPath = _containersPathConstraint.FindPath(path);
|
||||
if (string.IsNullOrEmpty(matchedPath)) {
|
||||
throw new ApplicationException("404 - should not have passed path constraint");
|
||||
}
|
||||
public ActionResult Display(int id, PagerParameters pagerParameters) {
|
||||
|
||||
var hits = _contentManager
|
||||
.Query<RoutePart, RoutePartRecord>(VersionOptions.Published)
|
||||
.Where(r => r.Path == matchedPath)
|
||||
.Slice(0, 2);
|
||||
var container = _contentManager.Get(id).As<ContainerPart>();
|
||||
if (container==null)
|
||||
return HttpNotFound(T("Container not found").Text);
|
||||
|
||||
if (hits.Count() == 0) {
|
||||
throw new ApplicationException("404 - should not have passed path constraint");
|
||||
}
|
||||
|
||||
if (hits.Count() != 1) {
|
||||
throw new ApplicationException("Ambiguous content");
|
||||
}
|
||||
|
||||
var container = _contentManager.Get(hits.Single().Id);
|
||||
container.As<ContainerPart>().PagerParameters = pagerParameters;
|
||||
// TODO: (PH) Find a way to apply PagerParameters via a driver so we can lose this controller
|
||||
container.PagerParameters = pagerParameters;
|
||||
var model = _contentManager.BuildDisplay(container, "Detail");
|
||||
|
||||
return new ShapeResult(this, model);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -17,6 +17,7 @@ using System.Web.Routing;
|
||||
using Orchard.Settings;
|
||||
using Orchard.Core.Feeds;
|
||||
using Orchard.UI.Navigation;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
|
||||
namespace Orchard.Core.Containers.Drivers {
|
||||
public class ContainerPartDriver : ContentPartDriver<ContainerPart> {
|
||||
@@ -60,8 +61,9 @@ namespace Orchard.Core.Containers.Drivers {
|
||||
|
||||
var descendingOrder = part.OrderByDirection == (int)OrderByDirection.Descending;
|
||||
query = query.OrderBy(part.OrderByProperty, descendingOrder);
|
||||
|
||||
_feedManager.Register(container.As<RoutePart>().Title, "rss", new RouteValueDictionary { { "containerid", container.Id } });
|
||||
var metadata = container.ContentManager.GetItemMetadata(container);
|
||||
if (metadata!=null)
|
||||
_feedManager.Register(metadata.DisplayText, "rss", new RouteValueDictionary { { "containerid", container.Id } });
|
||||
|
||||
var pager = new Pager(_siteService.GetSiteSettings(), part.PagerParameters);
|
||||
pager.PageSize = part.PagerParameters.PageSize != null && part.Paginated
|
||||
|
@@ -9,6 +9,7 @@ using Orchard.Core.Common.Models;
|
||||
using Orchard.Data;
|
||||
using Orchard.Core.Containers.Extensions;
|
||||
using Orchard.ContentManagement;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Orchard.Core.Containers.Handlers {
|
||||
public class ContainerPartHandler : ContentHandler {
|
||||
@@ -25,6 +26,13 @@ namespace Orchard.Core.Containers.Handlers {
|
||||
part.Record.OrderByProperty = part.Is<CommonPart>() ? "CommonPart.CreatedUtc" : string.Empty;
|
||||
part.Record.OrderByDirection = (int)OrderByDirection.Descending;
|
||||
});
|
||||
OnGetContentItemMetadata<ContainerPart>((context, part) => {
|
||||
context.Metadata.DisplayRouteValues = new RouteValueDictionary {
|
||||
{"Area", "Containers"},
|
||||
{"Controller", "Item"},
|
||||
{"Action", "Display"},
|
||||
{"id", context.ContentItem.Id}
|
||||
};});
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,42 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Orchard.Mvc.Routes;
|
||||
|
||||
namespace Orchard.Core.Containers {
|
||||
public class Routes : IRouteProvider {
|
||||
private readonly IContainersPathConstraint _containersPathConstraint;
|
||||
|
||||
public Routes(IContainersPathConstraint containersPathConstraint) {
|
||||
_containersPathConstraint = containersPathConstraint;
|
||||
}
|
||||
|
||||
public void GetRoutes(ICollection<RouteDescriptor> routes) {
|
||||
foreach (var routeDescriptor in GetRoutes())
|
||||
routes.Add(routeDescriptor);
|
||||
}
|
||||
|
||||
public IEnumerable<RouteDescriptor> GetRoutes() {
|
||||
return new[] {
|
||||
new RouteDescriptor {
|
||||
Priority = 15,
|
||||
Route = new Route(
|
||||
"{*path}",
|
||||
new RouteValueDictionary {
|
||||
{"area", "Containers"},
|
||||
{"controller", "Item"},
|
||||
{"action", "Display"}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"path", _containersPathConstraint}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"area", "Containers"}
|
||||
},
|
||||
new MvcRouteHandler())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Core.Containers.Models;
|
||||
using Orchard.Core.Routable.Models;
|
||||
using Orchard.Environment;
|
||||
using Orchard.Logging;
|
||||
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;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
void IOrchardShellEvents.Activated() {
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void IOrchardShellEvents.Terminating() {
|
||||
}
|
||||
|
||||
void IBackgroundTask.Sweep() {
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void Refresh() {
|
||||
try {
|
||||
var routeParts = _contentManager.Query<RoutePart, RoutePartRecord>().Join<ContainerPartRecord>().List();
|
||||
_containersPathConstraint.SetPaths(routeParts.Select(x => x.Path));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Logger.Error(ex, "Error while setting path constraints for containers.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user