mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-07-19 12:09:20 +08:00
Handling slashed in blog routes (with archive and rsd)
--HG-- branch : autoroute
This commit is contained in:
parent
49cdb191fd
commit
367066e741
@ -1,5 +1,5 @@
|
|||||||
81cb672c85fd980dd3db0515544b79a918e5eb69 src/Orchard.Web/Modules/Orchard.Alias
|
81cb672c85fd980dd3db0515544b79a918e5eb69 src/Orchard.Web/Modules/Orchard.Alias
|
||||||
a3329c82a2636eb166c46f3cfdadd18eca4e4d7f src/Orchard.Web/Modules/Orchard.Autoroute
|
f142e9e8cebf92caf3ca091d6e54849e02a27a4c src/Orchard.Web/Modules/Orchard.Autoroute
|
||||||
c54cb640d6bc14c51b9fb9bd78231bb0facec067 src/Orchard.Web/Modules/Orchard.Forms
|
c54cb640d6bc14c51b9fb9bd78231bb0facec067 src/Orchard.Web/Modules/Orchard.Forms
|
||||||
c27801666ed3e8f9b9c7979a837e7d770763352a src/Orchard.Web/Modules/Orchard.Projections
|
c27801666ed3e8f9b9c7979a837e7d770763352a src/Orchard.Web/Modules/Orchard.Projections
|
||||||
a1ef39ba4e2d0cd78b3c91d6150e841793acb34b src/Orchard.Web/Modules/Orchard.Routable
|
a1ef39ba4e2d0cd78b3c91d6150e841793acb34b src/Orchard.Web/Modules/Orchard.Routable
|
||||||
|
@ -58,14 +58,10 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
return View((object)viewModel);
|
return View((object)viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult Item(string blogPath, PagerParameters pagerParameters) {
|
public ActionResult Item(int blogId, PagerParameters pagerParameters) {
|
||||||
// TODO: (PH:Autoroute) Should use Containers so we can lose this action and rely on ContainerPartDriver instead
|
|
||||||
Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
|
Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
|
||||||
var correctedPath = _blogPathConstraint.FindPath(blogPath);
|
|
||||||
if (correctedPath == null)
|
|
||||||
return HttpNotFound();
|
|
||||||
|
|
||||||
var blogPart = _blogService.Get(correctedPath);
|
var blogPart = _blogService.Get(blogId, VersionOptions.Published).As<BlogPart>();
|
||||||
if (blogPart == null)
|
if (blogPart == null)
|
||||||
return HttpNotFound();
|
return HttpNotFound();
|
||||||
|
|
||||||
|
@ -2,13 +2,11 @@ using System.Linq;
|
|||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using Orchard.Blogs.Extensions;
|
using Orchard.Blogs.Extensions;
|
||||||
using Orchard.Blogs.Models;
|
using Orchard.Blogs.Models;
|
||||||
|
using Orchard.Blogs.Routing;
|
||||||
using Orchard.Blogs.Services;
|
using Orchard.Blogs.Services;
|
||||||
using Orchard.ContentManagement;
|
|
||||||
using Orchard.Core.Feeds;
|
using Orchard.Core.Feeds;
|
||||||
using Orchard.DisplayManagement;
|
using Orchard.DisplayManagement;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
using Orchard.Mvc;
|
|
||||||
using Orchard.Security;
|
|
||||||
using Orchard.Themes;
|
using Orchard.Themes;
|
||||||
|
|
||||||
namespace Orchard.Blogs.Controllers {
|
namespace Orchard.Blogs.Controllers {
|
||||||
@ -18,17 +16,20 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
private readonly IBlogService _blogService;
|
private readonly IBlogService _blogService;
|
||||||
private readonly IBlogPostService _blogPostService;
|
private readonly IBlogPostService _blogPostService;
|
||||||
private readonly IFeedManager _feedManager;
|
private readonly IFeedManager _feedManager;
|
||||||
|
private readonly IArchiveConstraint _archiveConstraint;
|
||||||
|
|
||||||
public BlogPostController(
|
public BlogPostController(
|
||||||
IOrchardServices services,
|
IOrchardServices services,
|
||||||
IBlogService blogService,
|
IBlogService blogService,
|
||||||
IBlogPostService blogPostService,
|
IBlogPostService blogPostService,
|
||||||
IFeedManager feedManager,
|
IFeedManager feedManager,
|
||||||
IShapeFactory shapeFactory) {
|
IShapeFactory shapeFactory,
|
||||||
|
IArchiveConstraint archiveConstraint) {
|
||||||
_services = services;
|
_services = services;
|
||||||
_blogService = blogService;
|
_blogService = blogService;
|
||||||
_blogPostService = blogPostService;
|
_blogPostService = blogPostService;
|
||||||
_feedManager = feedManager;
|
_feedManager = feedManager;
|
||||||
|
_archiveConstraint = archiveConstraint;
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
Shape = shapeFactory;
|
Shape = shapeFactory;
|
||||||
}
|
}
|
||||||
@ -36,15 +37,22 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
dynamic Shape { get; set; }
|
dynamic Shape { get; set; }
|
||||||
public Localizer T { get; set; }
|
public Localizer T { get; set; }
|
||||||
|
|
||||||
public ActionResult ListByArchive(string blogPath, string archiveData) {
|
public ActionResult ListByArchive(string path) {
|
||||||
//TODO: (erikpo) Move looking up the current blog up into a modelbinder
|
|
||||||
|
var blogPath = _archiveConstraint.FindPath(path);
|
||||||
|
var archive = _archiveConstraint.FindArchiveData(path);
|
||||||
|
|
||||||
|
if (blogPath == null)
|
||||||
|
return HttpNotFound();
|
||||||
|
|
||||||
|
if (archive == null)
|
||||||
|
return HttpNotFound();
|
||||||
|
|
||||||
BlogPart blogPart = _blogService.Get(blogPath);
|
BlogPart blogPart = _blogService.Get(blogPath);
|
||||||
|
|
||||||
if (blogPart == null)
|
if (blogPart == null)
|
||||||
return HttpNotFound();
|
return HttpNotFound();
|
||||||
|
|
||||||
var archive = new ArchiveData(archiveData);
|
|
||||||
|
|
||||||
var list = Shape.List();
|
var list = Shape.List();
|
||||||
list.AddRange(_blogPostService.Get(blogPart, archive).Select(b => _services.ContentManager.BuildDisplay(b, "Summary")));
|
list.AddRange(_blogPostService.Get(blogPart, archive).Select(b => _services.ContentManager.BuildDisplay(b, "Summary")));
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ using System.Web.Mvc;
|
|||||||
using System.Web.Routing;
|
using System.Web.Routing;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Orchard.Blogs.Models;
|
using Orchard.Blogs.Models;
|
||||||
|
using Orchard.Blogs.Routing;
|
||||||
using Orchard.Blogs.Services;
|
using Orchard.Blogs.Services;
|
||||||
using Orchard.Environment.Extensions;
|
using Orchard.Environment.Extensions;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
@ -11,19 +12,30 @@ namespace Orchard.Blogs.Controllers {
|
|||||||
[OrchardFeature("Orchard.Blogs.RemotePublishing")]
|
[OrchardFeature("Orchard.Blogs.RemotePublishing")]
|
||||||
public class RemoteBlogPublishingController : Controller {
|
public class RemoteBlogPublishingController : Controller {
|
||||||
private readonly IBlogService _blogService;
|
private readonly IBlogService _blogService;
|
||||||
|
private readonly IRsdConstraint _rsdConstraint;
|
||||||
private readonly RouteCollection _routeCollection;
|
private readonly RouteCollection _routeCollection;
|
||||||
|
|
||||||
public RemoteBlogPublishingController(IOrchardServices services, IBlogService blogService, RouteCollection routeCollection) {
|
public RemoteBlogPublishingController(
|
||||||
|
IOrchardServices services,
|
||||||
|
IBlogService blogService,
|
||||||
|
IRsdConstraint rsdConstraint,
|
||||||
|
RouteCollection routeCollection) {
|
||||||
_blogService = blogService;
|
_blogService = blogService;
|
||||||
|
_rsdConstraint = rsdConstraint;
|
||||||
_routeCollection = routeCollection;
|
_routeCollection = routeCollection;
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ILogger Logger { get; set; }
|
protected ILogger Logger { get; set; }
|
||||||
|
|
||||||
public ActionResult Rsd(string blogPath) {
|
public ActionResult Rsd(string path) {
|
||||||
Logger.Debug("RSD requested");
|
Logger.Debug("RSD requested");
|
||||||
|
|
||||||
|
var blogPath = _rsdConstraint.FindPath(path);
|
||||||
|
|
||||||
|
if (blogPath == null)
|
||||||
|
return HttpNotFound();
|
||||||
|
|
||||||
BlogPart blogPart = _blogService.Get(blogPath);
|
BlogPart blogPart = _blogService.Get(blogPath);
|
||||||
|
|
||||||
if (blogPart == null)
|
if (blogPart == null)
|
||||||
|
@ -81,8 +81,11 @@
|
|||||||
<Compile Include="Permissions.cs" />
|
<Compile Include="Permissions.cs" />
|
||||||
<Compile Include="Routing\BlogPathConstraint.cs" />
|
<Compile Include="Routing\BlogPathConstraint.cs" />
|
||||||
<Compile Include="Routing\BlogPathConstraintUpdator.cs" />
|
<Compile Include="Routing\BlogPathConstraintUpdator.cs" />
|
||||||
|
<Compile Include="Routing\ArchiveConstraint.cs" />
|
||||||
|
<Compile Include="Routing\IArchiveConstraint.cs" />
|
||||||
|
<Compile Include="Routing\RsdConstraint.cs" />
|
||||||
|
<Compile Include="Routing\IRsdConstraint.cs" />
|
||||||
<Compile Include="Routing\IBlogPathConstraint.cs" />
|
<Compile Include="Routing\IBlogPathConstraint.cs" />
|
||||||
<Compile Include="Routing\IsArchiveConstraint.cs" />
|
|
||||||
<Compile Include="Security\BlogAuthorizationEventHandler.cs" />
|
<Compile Include="Security\BlogAuthorizationEventHandler.cs" />
|
||||||
<Compile Include="Services\BlogService.cs" />
|
<Compile Include="Services\BlogService.cs" />
|
||||||
<Compile Include="Controllers\BlogController.cs" />
|
<Compile Include="Controllers\BlogController.cs" />
|
||||||
|
@ -6,10 +6,14 @@ using Orchard.Mvc.Routes;
|
|||||||
|
|
||||||
namespace Orchard.Blogs {
|
namespace Orchard.Blogs {
|
||||||
public class Routes : IRouteProvider {
|
public class Routes : IRouteProvider {
|
||||||
private readonly IBlogPathConstraint _blogPathConstraint;
|
private readonly IArchiveConstraint _archiveConstraint;
|
||||||
|
private readonly IRsdConstraint _rsdConstraint;
|
||||||
|
|
||||||
public Routes(IBlogPathConstraint blogPathConstraint) {
|
public Routes(
|
||||||
_blogPathConstraint = blogPathConstraint;
|
IArchiveConstraint archiveConstraint,
|
||||||
|
IRsdConstraint rsdConstraint) {
|
||||||
|
_archiveConstraint = archiveConstraint;
|
||||||
|
_rsdConstraint = rsdConstraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GetRoutes(ICollection<RouteDescriptor> routes) {
|
public void GetRoutes(ICollection<RouteDescriptor> routes) {
|
||||||
@ -175,32 +179,14 @@ namespace Orchard.Blogs {
|
|||||||
},
|
},
|
||||||
new RouteDescriptor {
|
new RouteDescriptor {
|
||||||
Route = new Route(
|
Route = new Route(
|
||||||
"Archive/{*archiveData}",
|
"{*path}",
|
||||||
new RouteValueDictionary {
|
|
||||||
{"blogPath", ""},
|
|
||||||
{"area", "Orchard.Blogs"},
|
|
||||||
{"controller", "BlogPost"},
|
|
||||||
{"action", "ListByArchive"}
|
|
||||||
},
|
|
||||||
new RouteValueDictionary {
|
|
||||||
{"archiveData", new IsArchiveConstraint()}
|
|
||||||
},
|
|
||||||
new RouteValueDictionary {
|
|
||||||
{"area", "Orchard.Blogs"}
|
|
||||||
},
|
|
||||||
new MvcRouteHandler())
|
|
||||||
},
|
|
||||||
new RouteDescriptor {
|
|
||||||
Route = new Route(
|
|
||||||
"{blogPath}/Archive/{*archiveData}",
|
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"area", "Orchard.Blogs"},
|
{"area", "Orchard.Blogs"},
|
||||||
{"controller", "BlogPost"},
|
{"controller", "BlogPost"},
|
||||||
{"action", "ListByArchive"}
|
{"action", "ListByArchive"}
|
||||||
},
|
},
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"blogPath", _blogPathConstraint},
|
{"path", _archiveConstraint},
|
||||||
{"archiveData", new IsArchiveConstraint()}
|
|
||||||
},
|
},
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"area", "Orchard.Blogs"}
|
{"area", "Orchard.Blogs"}
|
||||||
@ -210,20 +196,20 @@ new RouteDescriptor {
|
|||||||
new RouteDescriptor {
|
new RouteDescriptor {
|
||||||
Priority = 11,
|
Priority = 11,
|
||||||
Route = new Route(
|
Route = new Route(
|
||||||
"{blogPath}/rsd",
|
"{*path}",
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"area", "Orchard.Blogs"},
|
{"area", "Orchard.Blogs"},
|
||||||
{"controller", "RemoteBlogPublishing"},
|
{"controller", "RemoteBlogPublishing"},
|
||||||
{"action", "Rsd"}
|
{"action", "Rsd"}
|
||||||
},
|
},
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"blogPath", _blogPathConstraint}
|
{"path", _rsdConstraint}
|
||||||
},
|
},
|
||||||
new RouteValueDictionary {
|
new RouteValueDictionary {
|
||||||
{"area", "Orchard.Blogs"}
|
{"area", "Orchard.Blogs"}
|
||||||
},
|
},
|
||||||
new MvcRouteHandler())
|
new MvcRouteHandler())
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
using System;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Routing;
|
||||||
|
using Orchard.Blogs.Models;
|
||||||
|
|
||||||
|
namespace Orchard.Blogs.Routing {
|
||||||
|
public class ArchiveConstraint : IArchiveConstraint {
|
||||||
|
private readonly IBlogPathConstraint _blogPathConstraint;
|
||||||
|
|
||||||
|
public ArchiveConstraint(IBlogPathConstraint blogPathConstraint) {
|
||||||
|
_blogPathConstraint = blogPathConstraint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) {
|
||||||
|
|
||||||
|
object value;
|
||||||
|
if (values.TryGetValue(parameterName, out value)) {
|
||||||
|
var parameterValue = Convert.ToString(value);
|
||||||
|
|
||||||
|
var path = FindPath(parameterValue);
|
||||||
|
if (path == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var archiveData = FindArchiveData(parameterValue);
|
||||||
|
if (archiveData == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _blogPathConstraint.FindPath(path) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FindPath(string path) {
|
||||||
|
var archiveIndex = path.IndexOf("/archive/", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
if (archiveIndex == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.Substring(0, archiveIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArchiveData FindArchiveData(string path) {
|
||||||
|
var archiveIndex = path.IndexOf("/archive/", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
if (archiveIndex == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new ArchiveData(path.Substring(archiveIndex + "/archive/".Length));
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
using System.Web.Routing;
|
||||||
|
using Orchard.Blogs.Models;
|
||||||
|
|
||||||
|
namespace Orchard.Blogs.Routing {
|
||||||
|
public interface IArchiveConstraint : IRouteConstraint, ISingletonDependency {
|
||||||
|
string FindPath(string path);
|
||||||
|
ArchiveData FindArchiveData(string path);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
using System.Web.Routing;
|
||||||
|
|
||||||
|
namespace Orchard.Blogs.Routing {
|
||||||
|
public interface IRsdConstraint : IRouteConstraint, ISingletonDependency {
|
||||||
|
string FindPath(string path);
|
||||||
|
}
|
||||||
|
}
|
@ -1,23 +0,0 @@
|
|||||||
using System.Web;
|
|
||||||
using System.Web.Routing;
|
|
||||||
using Orchard.Blogs.Models;
|
|
||||||
|
|
||||||
namespace Orchard.Blogs.Routing {
|
|
||||||
public class IsArchiveConstraint : IRouteConstraint {
|
|
||||||
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values,
|
|
||||||
RouteDirection routeDirection) {
|
|
||||||
if(values[parameterName] == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
var archiveData = new ArchiveData(values[parameterName].ToString());
|
|
||||||
archiveData.ToDateTime();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Routing;
|
||||||
|
|
||||||
|
namespace Orchard.Blogs.Routing {
|
||||||
|
public class RsdConstraint : IRsdConstraint {
|
||||||
|
private readonly IBlogPathConstraint _blogPathConstraint;
|
||||||
|
|
||||||
|
public RsdConstraint(IBlogPathConstraint blogPathConstraint) {
|
||||||
|
_blogPathConstraint = blogPathConstraint;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
var path = FindPath(parameterValue);
|
||||||
|
if(path == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _blogPathConstraint.FindPath(path) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FindPath(string path) {
|
||||||
|
if (!path.EndsWith("/rsd", StringComparison.OrdinalIgnoreCase)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.Substring(0, path.Length - "/rsd".Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user