diff --git a/src/Orchard.Web/Core/Orchard.Core.csproj b/src/Orchard.Web/Core/Orchard.Core.csproj index c06905952..0c9308d99 100644 --- a/src/Orchard.Web/Core/Orchard.Core.csproj +++ b/src/Orchard.Web/Core/Orchard.Core.csproj @@ -104,6 +104,7 @@ + diff --git a/src/Orchard.Web/Core/Routable/Events/ISlugEventHandler.cs b/src/Orchard.Web/Core/Routable/Events/ISlugEventHandler.cs new file mode 100644 index 000000000..a178aed71 --- /dev/null +++ b/src/Orchard.Web/Core/Routable/Events/ISlugEventHandler.cs @@ -0,0 +1,17 @@ +using Orchard.Events; + +namespace Orchard.Core.Routable.Events { + public interface ISlugEventHandler : IEventHandler { + void FillingSlugFromTitle(FillSlugContext context); + void FilledSlugFromTitle(FillSlugContext context); + } + + public class FillSlugContext { + public FillSlugContext(string slug) { + Slug = slug; + } + + public string Slug { get; set; } + public bool Adjusted { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Routable/Services/RoutableService.cs b/src/Orchard.Web/Core/Routable/Services/RoutableService.cs index 68dc30218..889720db9 100644 --- a/src/Orchard.Web/Core/Routable/Services/RoutableService.cs +++ b/src/Orchard.Web/Core/Routable/Services/RoutableService.cs @@ -7,14 +7,17 @@ using System.Text.RegularExpressions; using Orchard.ContentManagement; using Orchard.ContentManagement.Aspects; using Orchard.Core.Common.Models; +using Orchard.Core.Routable.Events; using Orchard.Core.Routable.Models; namespace Orchard.Core.Routable.Services { public class RoutableService : IRoutableService { private readonly IContentManager _contentManager; + private readonly IEnumerable _slugEventHandlers; - public RoutableService(IContentManager contentManager) { + public RoutableService(IContentManager contentManager, IEnumerable slugEventHandlers) { _contentManager = contentManager; + _slugEventHandlers = slugEventHandlers; } public void FixContainedPaths(IRoutableAspect part) { @@ -47,18 +50,29 @@ namespace Orchard.Core.Routable.Services { if (!string.IsNullOrEmpty(model.Slug) || string.IsNullOrEmpty(model.Title)) return; - var slug = model.Title; - var disallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s\""\<\>]+"); + FillSlugContext slugContext = new FillSlugContext(model.Title); - slug = disallowed.Replace(slug, "-"); - slug = slug.Trim('-'); + foreach(ISlugEventHandler slugEventHandler in _slugEventHandlers) { + slugEventHandler.FillingSlugFromTitle(slugContext); + } - if (slug.Length > 1000) - slug = slug.Substring(0, 1000); + if (!slugContext.Adjusted) { + var disallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s\""\<\>]+"); - // dots are not allowed at the begin and the end of routes - slug = slug.Trim('.'); - model.Slug = RemoveDiacritics(slug.ToLower()); + slugContext.Slug = disallowed.Replace(slugContext.Slug, "-").Trim('-'); + + if (slugContext.Slug.Length > 1000) + slugContext.Slug = slugContext.Slug.Substring(0, 1000); + + // dots are not allowed at the begin and the end of routes + slugContext.Slug = RemoveDiacritics(slugContext.Slug.Trim('.').ToLower()); + } + + foreach (ISlugEventHandler slugEventHandler in _slugEventHandlers) { + slugEventHandler.FilledSlugFromTitle(slugContext); + } + + model.Slug = slugContext.Slug; } public string GenerateUniqueSlug(IRoutableAspect part, IEnumerable existingPaths) {