#17261 Changing BlogSlugConstraint to BlogPathContraint to handle homepage blogs

Work Item: 17261

--HG--
branch : dev
extra : transplant_source : Y%BC%1F%0E%A2%C5%10%BE%3B%82P%21%FC%FA%ED%FE%A7%26%9B%92
This commit is contained in:
Sebastien Ros
2011-01-31 13:25:16 -08:00
parent fc261cdb3a
commit 2680f394ba
15 changed files with 122 additions and 88 deletions

View File

@@ -24,7 +24,7 @@ namespace Orchard.Blogs.Controllers {
private readonly IBlogPostService _blogPostService; private readonly IBlogPostService _blogPostService;
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly ITransactionManager _transactionManager; private readonly ITransactionManager _transactionManager;
private readonly IBlogSlugConstraint _blogSlugConstraint; private readonly IBlogPathConstraint _blogPathConstraint;
private readonly ISiteService _siteService; private readonly ISiteService _siteService;
public BlogAdminController( public BlogAdminController(
@@ -33,7 +33,7 @@ namespace Orchard.Blogs.Controllers {
IBlogPostService blogPostService, IBlogPostService blogPostService,
IContentManager contentManager, IContentManager contentManager,
ITransactionManager transactionManager, ITransactionManager transactionManager,
IBlogSlugConstraint blogSlugConstraint, IBlogPathConstraint blogPathConstraint,
ISiteService siteService, ISiteService siteService,
IShapeFactory shapeFactory) { IShapeFactory shapeFactory) {
Services = services; Services = services;
@@ -41,7 +41,7 @@ namespace Orchard.Blogs.Controllers {
_blogPostService = blogPostService; _blogPostService = blogPostService;
_contentManager = contentManager; _contentManager = contentManager;
_transactionManager = transactionManager; _transactionManager = transactionManager;
_blogSlugConstraint = blogSlugConstraint; _blogPathConstraint = blogPathConstraint;
_siteService = siteService; _siteService = siteService;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
Shape = shapeFactory; Shape = shapeFactory;
@@ -81,7 +81,7 @@ namespace Orchard.Blogs.Controllers {
} }
_contentManager.Publish(blog.ContentItem); _contentManager.Publish(blog.ContentItem);
_blogSlugConstraint.AddSlug(blog.As<IRoutableAspect>().GetEffectiveSlug()); _blogPathConstraint.AddPath(blog.As<IRoutableAspect>().Path);
return Redirect(Url.BlogForAdmin(blog)); return Redirect(Url.BlogForAdmin(blog));
} }
@@ -116,7 +116,7 @@ namespace Orchard.Blogs.Controllers {
} }
_contentManager.Publish(blog); _contentManager.Publish(blog);
_blogSlugConstraint.AddSlug(blog.As<IRoutableAspect>().GetEffectiveSlug()); _blogPathConstraint.AddPath(blog.As<IRoutableAspect>().Path);
Services.Notifier.Information(T("Blog information updated")); Services.Notifier.Information(T("Blog information updated"));
return Redirect(Url.BlogsForAdmin()); return Redirect(Url.BlogsForAdmin());

View File

@@ -20,7 +20,7 @@ namespace Orchard.Blogs.Controllers {
private readonly IOrchardServices _services; private readonly IOrchardServices _services;
private readonly IBlogService _blogService; private readonly IBlogService _blogService;
private readonly IBlogPostService _blogPostService; private readonly IBlogPostService _blogPostService;
private readonly IBlogSlugConstraint _blogSlugConstraint; private readonly IBlogPathConstraint _blogPathConstraint;
private readonly IFeedManager _feedManager; private readonly IFeedManager _feedManager;
private readonly IWorkContextAccessor _workContextAccessor; private readonly IWorkContextAccessor _workContextAccessor;
private readonly IHomePageProvider _routableHomePageProvider; private readonly IHomePageProvider _routableHomePageProvider;
@@ -30,7 +30,7 @@ namespace Orchard.Blogs.Controllers {
IOrchardServices services, IOrchardServices services,
IBlogService blogService, IBlogService blogService,
IBlogPostService blogPostService, IBlogPostService blogPostService,
IBlogSlugConstraint blogSlugConstraint, IBlogPathConstraint blogPathConstraint,
IFeedManager feedManager, IFeedManager feedManager,
IShapeFactory shapeFactory, IShapeFactory shapeFactory,
IWorkContextAccessor workContextAccessor, IWorkContextAccessor workContextAccessor,
@@ -39,7 +39,7 @@ namespace Orchard.Blogs.Controllers {
_services = services; _services = services;
_blogService = blogService; _blogService = blogService;
_blogPostService = blogPostService; _blogPostService = blogPostService;
_blogSlugConstraint = blogSlugConstraint; _blogPathConstraint = blogPathConstraint;
_feedManager = feedManager; _feedManager = feedManager;
_workContextAccessor = workContextAccessor; _workContextAccessor = workContextAccessor;
_siteService = siteService; _siteService = siteService;
@@ -64,13 +64,13 @@ namespace Orchard.Blogs.Controllers {
return View((object)viewModel); return View((object)viewModel);
} }
public ActionResult Item(string blogSlug, PagerParameters pagerParameters) { public ActionResult Item(string blogPath, PagerParameters pagerParameters) {
Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters); Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
var correctedSlug = _blogSlugConstraint.FindSlug(blogSlug); var correctedPath = _blogPathConstraint.FindPath(blogPath);
if (correctedSlug == null) if (correctedPath == null)
return HttpNotFound(); return HttpNotFound();
var blogPart = _blogService.Get(correctedSlug); var blogPart = _blogService.Get(correctedPath);
if (blogPart == null) if (blogPart == null)
return HttpNotFound(); return HttpNotFound();

View File

@@ -36,12 +36,12 @@ namespace Orchard.Blogs.Controllers {
public Localizer T { get; set; } public Localizer T { get; set; }
//TODO: (erikpo) Should think about moving the slug parameters and get calls and null checks up into a model binder or action filter //TODO: (erikpo) Should think about moving the slug parameters and get calls and null checks up into a model binder or action filter
public ActionResult Item(string blogSlug, string postSlug) { public ActionResult Item(string blogPath, string postSlug) {
if (!_services.Authorizer.Authorize(StandardPermissions.AccessFrontEnd, T("Couldn't view blog post"))) if (!_services.Authorizer.Authorize(StandardPermissions.AccessFrontEnd, T("Couldn't view blog post")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
//TODO: (erikpo) Move looking up the current blog up into a modelbinder //TODO: (erikpo) Move looking up the current blog up into a modelbinder
var blogPart = _blogService.Get(blogSlug); var blogPart = _blogService.Get(blogPath);
if (blogPart == null) if (blogPart == null)
return HttpNotFound(); return HttpNotFound();
@@ -55,9 +55,9 @@ namespace Orchard.Blogs.Controllers {
return View((object)model); return View((object)model);
} }
public ActionResult ListByArchive(string blogSlug, string archiveData) { public ActionResult ListByArchive(string blogPath, string archiveData) {
//TODO: (erikpo) Move looking up the current blog up into a modelbinder //TODO: (erikpo) Move looking up the current blog up into a modelbinder
BlogPart blogPart = _blogService.Get(blogSlug); BlogPart blogPart = _blogService.Get(blogPath);
if (blogPart == null) if (blogPart == null)
return HttpNotFound(); return HttpNotFound();

View File

@@ -21,10 +21,10 @@ namespace Orchard.Blogs.Controllers {
protected ILogger Logger { get; set; } protected ILogger Logger { get; set; }
public ActionResult Rsd(string blogSlug) { public ActionResult Rsd(string blogPath) {
Logger.Debug("RSD requested"); Logger.Debug("RSD requested");
BlogPart blogPart = _blogService.Get(blogSlug); BlogPart blogPart = _blogService.Get(blogPath);
if (blogPart == null) if (blogPart == null)
return HttpNotFound(); return HttpNotFound();

View File

@@ -1,5 +1,6 @@
using System.Linq; using System.Linq;
using Orchard.Blogs.Models; using Orchard.Blogs.Models;
using Orchard.Blogs.Routing;
using Orchard.Blogs.Services; using Orchard.Blogs.Services;
using Orchard.Blogs.ViewModels; using Orchard.Blogs.ViewModels;
using Orchard.ContentManagement; using Orchard.ContentManagement;
@@ -9,18 +10,22 @@ namespace Orchard.Blogs.Drivers {
public class BlogArchivesPartDriver : ContentPartDriver<BlogArchivesPart> { public class BlogArchivesPartDriver : ContentPartDriver<BlogArchivesPart> {
private readonly IBlogService _blogService; private readonly IBlogService _blogService;
private readonly IBlogPostService _blogPostService; private readonly IBlogPostService _blogPostService;
private readonly IBlogPathConstraint _blogPathConstraint;
public BlogArchivesPartDriver(IBlogService blogService, IBlogPostService blogPostService) { public BlogArchivesPartDriver(
IBlogService blogService,
IBlogPostService blogPostService,
IBlogPathConstraint blogPathConstraint) {
_blogService = blogService; _blogService = blogService;
_blogPostService = blogPostService; _blogPostService = blogPostService;
_blogPathConstraint = blogPathConstraint;
} }
protected override DriverResult Display(BlogArchivesPart part, string displayType, dynamic shapeHelper) { protected override DriverResult Display(BlogArchivesPart part, string displayType, dynamic shapeHelper) {
return ContentShape("Parts_Blogs_BlogArchives", return ContentShape("Parts_Blogs_BlogArchives",
() => { () => {
BlogPart blog = null; var path = _blogPathConstraint.FindPath(part.ForBlog);
if (!string.IsNullOrWhiteSpace(part.ForBlog)) BlogPart blog = _blogService.Get(path);
blog = _blogService.Get(part.ForBlog);
if (blog == null) if (blog == null)
return null; return null;
@@ -31,7 +36,7 @@ namespace Orchard.Blogs.Drivers {
protected override DriverResult Editor(BlogArchivesPart part, dynamic shapeHelper) { protected override DriverResult Editor(BlogArchivesPart part, dynamic shapeHelper) {
var viewModel = new BlogArchivesViewModel { var viewModel = new BlogArchivesViewModel {
Slug = part.ForBlog, Path = part.ForBlog,
Blogs = _blogService.Get().ToList().OrderBy(b => b.Name) Blogs = _blogService.Get().ToList().OrderBy(b => b.Name)
}; };
@@ -42,7 +47,7 @@ namespace Orchard.Blogs.Drivers {
protected override DriverResult Editor(BlogArchivesPart part, IUpdateModel updater, dynamic shapeHelper) { protected override DriverResult Editor(BlogArchivesPart part, IUpdateModel updater, dynamic shapeHelper) {
var viewModel = new BlogArchivesViewModel(); var viewModel = new BlogArchivesViewModel();
if (updater.TryUpdateModel(viewModel, Prefix, null, null)) { if (updater.TryUpdateModel(viewModel, Prefix, null, null)) {
part.ForBlog = viewModel.Slug; part.ForBlog = viewModel.Path;
} }
return Editor(part, shapeHelper); return Editor(part, shapeHelper);

View File

@@ -16,7 +16,7 @@ namespace Orchard.Blogs.Extensions {
} }
public static string Blog(this UrlHelper urlHelper, BlogPart blogPart) { public static string Blog(this UrlHelper urlHelper, BlogPart blogPart) {
return urlHelper.Action("Item", "Blog", new { blogSlug = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" }); return urlHelper.Action("Item", "Blog", new { blogPath = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" });
} }
public static string BlogLiveWriterManifest(this UrlHelper urlHelper, BlogPart blogPart) { public static string BlogLiveWriterManifest(this UrlHelper urlHelper, BlogPart blogPart) {
@@ -24,19 +24,19 @@ namespace Orchard.Blogs.Extensions {
} }
public static string BlogRsd(this UrlHelper urlHelper, BlogPart blogPart) { public static string BlogRsd(this UrlHelper urlHelper, BlogPart blogPart) {
return urlHelper.AbsoluteAction(() => urlHelper.Action("Rsd", "RemoteBlogPublishing", new { blogSlug = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" })); return urlHelper.AbsoluteAction(() => urlHelper.Action("Rsd", "RemoteBlogPublishing", new { blogPath = blogPart.As<IRoutableAspect>().Path, area = "Orchard.Blogs" }));
} }
public static string BlogArchiveYear(this UrlHelper urlHelper, BlogPart blogPart, int year) { public static string BlogArchiveYear(this UrlHelper urlHelper, BlogPart blogPart, int year) {
return urlHelper.Action("ListByArchive", "BlogPost", new { blogSlug = blogPart.As<IRoutableAspect>().Path, archiveData = year.ToString(), area = "Orchard.Blogs" }); return urlHelper.Action("ListByArchive", "BlogPost", new { blogPath = blogPart.As<IRoutableAspect>().Path, archiveData = year.ToString(), area = "Orchard.Blogs" });
} }
public static string BlogArchiveMonth(this UrlHelper urlHelper, BlogPart blogPart, int year, int month) { public static string BlogArchiveMonth(this UrlHelper urlHelper, BlogPart blogPart, int year, int month) {
return urlHelper.Action("ListByArchive", "BlogPost", new { blogSlug = blogPart.As<IRoutableAspect>().Path, archiveData = string.Format("{0}/{1}", year, month), area = "Orchard.Blogs" }); return urlHelper.Action("ListByArchive", "BlogPost", new { blogPath = blogPart.As<IRoutableAspect>().Path, archiveData = string.Format("{0}/{1}", year, month), area = "Orchard.Blogs" });
} }
public static string BlogArchiveDay(this UrlHelper urlHelper, BlogPart blogPart, int year, int month, int day) { public static string BlogArchiveDay(this UrlHelper urlHelper, BlogPart blogPart, int year, int month, int day) {
return urlHelper.Action("ListByArchive", "BlogPost", new { blogSlug = blogPart.As<IRoutableAspect>().Path, archiveData = string.Format("{0}/{1}/{2}", year, month, day), area = "Orchard.Blogs" }); return urlHelper.Action("ListByArchive", "BlogPost", new { blogPath = blogPart.As<IRoutableAspect>().Path, archiveData = string.Format("{0}/{1}/{2}", year, month, day), area = "Orchard.Blogs" });
} }
public static string BlogForAdmin(this UrlHelper urlHelper, BlogPart blogPart) { public static string BlogForAdmin(this UrlHelper urlHelper, BlogPart blogPart) {
@@ -60,7 +60,7 @@ namespace Orchard.Blogs.Extensions {
} }
public static string BlogPost(this UrlHelper urlHelper, BlogPostPart blogPostPart) { public static string BlogPost(this UrlHelper urlHelper, BlogPostPart blogPostPart) {
return urlHelper.Action("Item", "BlogPost", new { blogSlug = blogPostPart.BlogPart.As<IRoutableAspect>().Path, postSlug = blogPostPart.As<IRoutableAspect>().GetEffectiveSlug(), area = "Orchard.Blogs" }); return urlHelper.Action("Item", "BlogPost", new { blogPath = blogPostPart.BlogPart.As<IRoutableAspect>().Path, postSlug = blogPostPart.As<IRoutableAspect>().GetEffectiveSlug(), area = "Orchard.Blogs" });
} }
public static string BlogPostEdit(this UrlHelper urlHelper, BlogPostPart blogPostPart) { public static string BlogPostEdit(this UrlHelper urlHelper, BlogPostPart blogPostPart) {

View File

@@ -16,22 +16,22 @@ namespace Orchard.Blogs.Handlers {
[UsedImplicitly] [UsedImplicitly]
public class BlogPartHandler : ContentHandler { public class BlogPartHandler : ContentHandler {
private readonly IWorkContextAccessor _workContextAccessor; private readonly IWorkContextAccessor _workContextAccessor;
private readonly IBlogSlugConstraint _blogSlugConstraint; private readonly IBlogPathConstraint _blogPathConstraint;
private readonly IHomePageProvider _routableHomePageProvider; private readonly IHomePageProvider _routableHomePageProvider;
public BlogPartHandler(IRepository<BlogPartRecord> repository, IWorkContextAccessor workContextAccessor, IEnumerable<IHomePageProvider> homePageProviders, IBlogSlugConstraint blogSlugConstraint) { public BlogPartHandler(IRepository<BlogPartRecord> repository, IWorkContextAccessor workContextAccessor, IEnumerable<IHomePageProvider> homePageProviders, IBlogPathConstraint blogPathConstraint) {
_workContextAccessor = workContextAccessor; _workContextAccessor = workContextAccessor;
_blogSlugConstraint = blogSlugConstraint; _blogPathConstraint = blogPathConstraint;
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name); _routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name);
Filters.Add(StorageFilter.For(repository)); Filters.Add(StorageFilter.For(repository));
Action<PublishContentContext, RoutePart> publishedHandler = (context, route) => { Action<PublishContentContext, RoutePart> publishedHandler = (context, route) => {
if (route.Is<BlogPart>()) { if (route.Is<BlogPart>()) {
if (route.ContentItem.Id != 0 && route.PromoteToHomePage) if (route.ContentItem.Id != 0 && route.PromoteToHomePage)
_blogSlugConstraint.AddSlug(""); _blogPathConstraint.AddPath("");
} }
else if (route.ContentItem.Id != 0 && route.PromoteToHomePage) { else if (route.ContentItem.Id != 0 && route.PromoteToHomePage) {
_blogSlugConstraint.RemoveSlug(""); _blogPathConstraint.RemovePath("");
} }
}; };

View File

@@ -6,10 +6,10 @@ using Orchard.Mvc.Routes;
namespace Orchard.Blogs { namespace Orchard.Blogs {
public class Routes : IRouteProvider { public class Routes : IRouteProvider {
private readonly IBlogSlugConstraint _blogSlugConstraint; private readonly IBlogPathConstraint _blogPathConstraint;
public Routes(IBlogSlugConstraint blogSlugConstraint) { public Routes(IBlogPathConstraint blogPathConstraint) {
_blogSlugConstraint = blogSlugConstraint; _blogPathConstraint = blogPathConstraint;
} }
public void GetRoutes(ICollection<RouteDescriptor> routes) { public void GetRoutes(ICollection<RouteDescriptor> routes) {
@@ -175,14 +175,31 @@ namespace Orchard.Blogs {
}, },
new RouteDescriptor { new RouteDescriptor {
Route = new Route( Route = new Route(
"{blogSlug}/Archive/{*archiveData}", "Archive/{*archiveData}",
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 {
{"blogSlug", _blogSlugConstraint}, {"blogPath", _blogPathConstraint},
{"archiveData", new IsArchiveConstraint()} {"archiveData", new IsArchiveConstraint()}
}, },
new RouteValueDictionary { new RouteValueDictionary {
@@ -193,14 +210,14 @@ namespace Orchard.Blogs {
new RouteDescriptor { new RouteDescriptor {
Priority = 11, Priority = 11,
Route = new Route( Route = new Route(
"{blogSlug}/rsd", "{blogPath}/rsd",
new RouteValueDictionary { new RouteValueDictionary {
{"area", "Orchard.Blogs"}, {"area", "Orchard.Blogs"},
{"controller", "RemoteBlogPublishing"}, {"controller", "RemoteBlogPublishing"},
{"action", "Rsd"} {"action", "Rsd"}
}, },
new RouteValueDictionary { new RouteValueDictionary {
{"blogSlug", _blogSlugConstraint} {"blogPath", _blogPathConstraint}
}, },
new RouteValueDictionary { new RouteValueDictionary {
{"area", "Orchard.Blogs"} {"area", "Orchard.Blogs"}
@@ -210,14 +227,14 @@ namespace Orchard.Blogs {
new RouteDescriptor { new RouteDescriptor {
Priority = 11, Priority = 11,
Route = new Route( Route = new Route(
"{blogSlug}/{postSlug}", "{blogPath}/{postSlug}",
new RouteValueDictionary { new RouteValueDictionary {
{"area", "Orchard.Blogs"}, {"area", "Orchard.Blogs"},
{"controller", "BlogPost"}, {"controller", "BlogPost"},
{"action", "Item"} {"action", "Item"}
}, },
new RouteValueDictionary { new RouteValueDictionary {
{"blogSlug", _blogSlugConstraint} {"blogPath", _blogPathConstraint}
}, },
new RouteValueDictionary { new RouteValueDictionary {
{"area", "Orchard.Blogs"} {"area", "Orchard.Blogs"}
@@ -227,15 +244,15 @@ namespace Orchard.Blogs {
new RouteDescriptor { new RouteDescriptor {
Priority = 11, Priority = 11,
Route = new Route( Route = new Route(
"{blogSlug}", "{blogPath}",
new RouteValueDictionary { new RouteValueDictionary {
{"area", "Orchard.Blogs"}, {"area", "Orchard.Blogs"},
{"controller", "Blog"}, {"controller", "Blog"},
{"action", "Item"}, {"action", "Item"},
{"blogSlug", ""} {"blogPath", ""}
}, },
new RouteValueDictionary { new RouteValueDictionary {
{"blogSlug", _blogSlugConstraint} {"blogPath", _blogPathConstraint}
}, },
new RouteValueDictionary { new RouteValueDictionary {
{"area", "Orchard.Blogs"} {"area", "Orchard.Blogs"}

View File

@@ -8,46 +8,55 @@ using Orchard.Logging;
namespace Orchard.Blogs.Routing { namespace Orchard.Blogs.Routing {
[UsedImplicitly] [UsedImplicitly]
public class BlogSlugConstraint : IBlogSlugConstraint { public class BlogPathConstraint : IBlogPathConstraint {
/// <summary> /// <summary>
/// Singleton object, per Orchard Shell instance. We need to protect concurrent access to the dictionary. /// Singleton object, per Orchard Shell instance. We need to protect concurrent access to the dictionary.
/// </summary> /// </summary>
private readonly object _syncLock = new object(); private readonly object _syncLock = new object();
private IDictionary<string, string> _slugs = new Dictionary<string, string>(); private IDictionary<string, string> _paths = new Dictionary<string, string>();
public BlogSlugConstraint() { public BlogPathConstraint() {
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
} }
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
public void SetSlugs(IEnumerable<string> slugs) { public void SetPaths(IEnumerable<string> paths) {
// Make a copy to avoid performing potential lazy computation inside the lock // Make a copy to avoid performing potential lazy computation inside the lock
var slugsArray = slugs.ToArray(); var pathArray = paths.ToArray();
lock (_syncLock) { lock (_syncLock) {
_slugs = slugsArray.Distinct(StringComparer.OrdinalIgnoreCase).ToDictionary(value => value, StringComparer.OrdinalIgnoreCase); _paths = pathArray.Distinct(StringComparer.OrdinalIgnoreCase).ToDictionary(value => value, StringComparer.OrdinalIgnoreCase);
} }
Logger.Debug("Blog slugs: {0}", string.Join(", ", slugsArray)); Logger.Debug("Blog paths: {0}", string.Join(", ", pathArray));
} }
public string FindSlug(string slug) { public string FindPath(string path) {
lock (_syncLock) { lock (_syncLock) {
string actual; string actual;
return _slugs.TryGetValue(slug, out actual) ? actual : slug; // path can be null for homepage
path = path ?? "";
return _paths.TryGetValue(path, out actual) ? actual : path;
} }
} }
public void AddSlug(string slug) { public void AddPath(string path) {
lock (_syncLock) { lock (_syncLock) {
_slugs[slug] = slug; // path can be null for homepage
path = path ?? "";
_paths[path] = path;
} }
} }
public void RemoveSlug(string slug) { public void RemovePath(string path) {
lock (_syncLock) { lock (_syncLock) {
_slugs.Remove(slug); // path can be null for homepage
path = path ?? "";
_paths.Remove(path);
} }
} }
@@ -60,7 +69,7 @@ namespace Orchard.Blogs.Routing {
var parameterValue = Convert.ToString(value); var parameterValue = Convert.ToString(value);
lock (_syncLock) { lock (_syncLock) {
return _slugs.ContainsKey(parameterValue); return _paths.ContainsKey(parameterValue);
} }
} }

View File

@@ -8,12 +8,12 @@ using Orchard.Tasks;
namespace Orchard.Blogs.Routing { namespace Orchard.Blogs.Routing {
[UsedImplicitly] [UsedImplicitly]
public class BlogSlugConstraintUpdator : IOrchardShellEvents, IBackgroundTask { public class BlogPathConstraintUpdator : IOrchardShellEvents, IBackgroundTask {
private readonly IBlogSlugConstraint _blogSlugConstraint; private readonly IBlogPathConstraint _blogPathConstraint;
private readonly IBlogService _blogService; private readonly IBlogService _blogService;
public BlogSlugConstraintUpdator(IBlogSlugConstraint blogSlugConstraint, IBlogService blogService) { public BlogPathConstraintUpdator(IBlogPathConstraint blogPathConstraint, IBlogService blogService) {
_blogSlugConstraint = blogSlugConstraint; _blogPathConstraint = blogPathConstraint;
_blogService = blogService; _blogService = blogService;
} }
@@ -29,7 +29,7 @@ namespace Orchard.Blogs.Routing {
} }
private void Refresh() { private void Refresh() {
_blogSlugConstraint.SetSlugs(_blogService.Get().Select(b => b.As<IRoutableAspect>().Path)); _blogPathConstraint.SetPaths(_blogService.Get().Select(b => b.As<IRoutableAspect>().Slug));
} }
} }
} }

View File

@@ -0,0 +1,11 @@
using System.Collections.Generic;
using System.Web.Routing;
namespace Orchard.Blogs.Routing {
public interface IBlogPathConstraint : IRouteConstraint, ISingletonDependency {
void SetPaths(IEnumerable<string> paths);
string FindPath(string path);
void AddPath(string path);
void RemovePath(string path);
}
}

View File

@@ -1,11 +0,0 @@
using System.Collections.Generic;
using System.Web.Routing;
namespace Orchard.Blogs.Routing {
public interface IBlogSlugConstraint : IRouteConstraint, ISingletonDependency {
void SetSlugs(IEnumerable<string> slugs);
string FindSlug(string slug);
void AddSlug(string slug);
void RemoveSlug(string slug);
}
}

View File

@@ -29,9 +29,9 @@ namespace Orchard.Blogs.Services {
} }
public BlogPostPart Get(BlogPart blogPart, string slug, VersionOptions versionOptions) { public BlogPostPart Get(BlogPart blogPart, string slug, VersionOptions versionOptions) {
var postSlug = blogPart.As<IRoutableAspect>().GetChildPath(slug); var postPath = blogPart.As<IRoutableAspect>().GetChildPath(slug);
return return
_contentManager.Query(versionOptions, "BlogPost").Join<RoutePartRecord>().Where(rr => rr.Path == postSlug). _contentManager.Query(versionOptions, "BlogPost").Join<RoutePartRecord>().Where(rr => rr.Path == postPath).
Join<CommonPartRecord>().Where(cr => cr.Container == blogPart.Record.ContentItemRecord).List(). Join<CommonPartRecord>().Where(cr => cr.Container == blogPart.Record.ContentItemRecord).List().
SingleOrDefault().As<BlogPostPart>(); SingleOrDefault().As<BlogPostPart>();
} }

View File

@@ -11,11 +11,11 @@ namespace Orchard.Blogs.Services {
[UsedImplicitly] [UsedImplicitly]
public class BlogService : IBlogService { public class BlogService : IBlogService {
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly IBlogSlugConstraint _blogSlugConstraint; private readonly IBlogPathConstraint _blogPathConstraint;
public BlogService(IContentManager contentManager, IBlogSlugConstraint blogSlugConstraint) { public BlogService(IContentManager contentManager, IBlogPathConstraint blogPathConstraint) {
_contentManager = contentManager; _contentManager = contentManager;
_blogSlugConstraint = blogSlugConstraint; _blogPathConstraint = blogPathConstraint;
} }
public BlogPart Get(string path) { public BlogPart Get(string path) {
@@ -39,9 +39,15 @@ namespace Orchard.Blogs.Services {
.List(); .List();
} }
public BlogPart GetFromSlug(string slug) {
return _contentManager.Query<BlogPart, BlogPartRecord>()
.Join<RoutePartRecord>().Where(rr => rr.Slug == slug)
.List().FirstOrDefault();
}
public void Delete(ContentItem blog) { public void Delete(ContentItem blog) {
_contentManager.Remove(blog); _contentManager.Remove(blog);
_blogSlugConstraint.RemoveSlug(blog.As<IRoutableAspect>().Path); _blogPathConstraint.RemovePath(blog.As<IRoutableAspect>().Path);
} }
} }
} }

View File

@@ -1,12 +1,9 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Orchard.Blogs.Models; using Orchard.Blogs.Models;
namespace Orchard.Blogs.ViewModels { namespace Orchard.Blogs.ViewModels {
public class BlogArchivesViewModel { public class BlogArchivesViewModel {
public string Slug { get; set; } public string Path { get; set; }
public IEnumerable<BlogPart> Blogs { get; set; } public IEnumerable<BlogPart> Blogs { get; set; }
} }
} }