Handling slashed in blog routes (with archive and rsd)

--HG--
branch : autoroute
This commit is contained in:
Sebastien Ros 2012-01-31 17:07:00 -08:00
parent 49cdb191fd
commit 367066e741
11 changed files with 167 additions and 68 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,7 @@
using System.Web.Routing;
namespace Orchard.Blogs.Routing {
public interface IRsdConstraint : IRouteConstraint, ISingletonDependency {
string FindPath(string path);
}
}

View File

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

View File

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