mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-09-23 12:53:33 +08:00

- Page edit actions changed over to use id instead of slug (others should follow suit since slug uniqueness is only guaranteed among published content items...where applicable, there is no notion of a "published" blog) --HG-- extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4045722
140 lines
6.1 KiB
C#
140 lines
6.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using System.Web.Routing;
|
|
using JetBrains.Annotations;
|
|
using Orchard.Blogs.Models;
|
|
using Orchard.Blogs.Services;
|
|
using Orchard.ContentManagement;
|
|
using Orchard.ContentManagement.Drivers;
|
|
using Orchard.Core.Common.Models;
|
|
using Orchard.Core.Common.Services;
|
|
using Orchard.Localization;
|
|
using Orchard.Mvc.ViewModels;
|
|
using Orchard.UI.Notify;
|
|
|
|
namespace Orchard.Blogs.Controllers {
|
|
[UsedImplicitly]
|
|
public class BlogDriver : ContentItemDriver<Blog> {
|
|
public readonly static ContentType ContentType = new ContentType {
|
|
Name = "blog",
|
|
DisplayName = "Blog"
|
|
};
|
|
|
|
private readonly IContentManager _contentManager;
|
|
private readonly IBlogService _blogService;
|
|
private readonly IBlogPostService _blogPostService;
|
|
private readonly IRoutableService _routableService;
|
|
private readonly IOrchardServices _orchardServices;
|
|
|
|
public BlogDriver(IContentManager contentManager, IBlogService blogService, IBlogPostService blogPostService, IRoutableService routableService, IOrchardServices orchardServices) {
|
|
_contentManager = contentManager;
|
|
_blogService = blogService;
|
|
_blogPostService = blogPostService;
|
|
_routableService = routableService;
|
|
_orchardServices = orchardServices;
|
|
T = NullLocalizer.Instance;
|
|
}
|
|
|
|
private Localizer T { get; set; }
|
|
|
|
protected override ContentType GetContentType() {
|
|
return ContentType;
|
|
}
|
|
|
|
protected override string Prefix { get { return ""; } }
|
|
|
|
protected override string GetDisplayText(Blog item) {
|
|
return item.Name;
|
|
}
|
|
|
|
protected override RouteValueDictionary GetDisplayRouteValues(Blog blog) {
|
|
return new RouteValueDictionary {
|
|
{"Area", "Orchard.Blogs"},
|
|
{"Controller", "Blog"},
|
|
{"Action", "Item"},
|
|
{"blogSlug", blog.Slug}
|
|
};
|
|
}
|
|
|
|
protected override RouteValueDictionary GetEditorRouteValues(Blog blog) {
|
|
return new RouteValueDictionary {
|
|
{"Area", "Orchard.Blogs"},
|
|
{"Controller", "Blog"},
|
|
{"Action", "Edit"},
|
|
{"blogSlug", blog.Slug}
|
|
};
|
|
}
|
|
|
|
protected override DriverResult Display(Blog blog, string displayType) {
|
|
|
|
IEnumerable<ContentItemViewModel<BlogPost>> blogPosts = null;
|
|
if (displayType.StartsWith("DetailAdmin")) {
|
|
blogPosts = _blogPostService.Get(blog, VersionOptions.Latest)
|
|
.Select(bp => _contentManager.BuildDisplayModel(bp, "SummaryAdmin"));
|
|
}
|
|
else if (displayType.StartsWith("Detail")) {
|
|
blogPosts = _blogPostService.Get(blog)
|
|
.Select(bp => _contentManager.BuildDisplayModel(bp, "Summary"));
|
|
}
|
|
|
|
return Combined(
|
|
ContentItemTemplate("Items/Blogs.Blog").LongestMatch(displayType, "Summary", "DetailAdmin", "SummaryAdmin"),
|
|
blogPosts == null ? null : ContentPartTemplate(blogPosts, "Parts/Blogs.BlogPost.List", "").Location("primary"));
|
|
}
|
|
|
|
protected override DriverResult Editor(Blog blog) {
|
|
return Combined(
|
|
ContentItemTemplate("Items/Blogs.Blog"),
|
|
ContentPartTemplate(blog, "Parts/Blogs.Blog.Fields").Location("primary", "1"));
|
|
}
|
|
|
|
protected override DriverResult Editor(Blog blog, IUpdateModel updater) {
|
|
updater.TryUpdateModel(blog, Prefix, null, null);
|
|
|
|
//todo: (heskew) something better needs to be done with this...still feels shoehorned in here
|
|
ProcessSlug(blog, updater);
|
|
|
|
return Combined(
|
|
ContentItemTemplate("Items/Blogs.Blog"),
|
|
ContentPartTemplate(blog, "Parts/Blogs.Blog.Fields").Location("primary", "1"));
|
|
}
|
|
|
|
private void ProcessSlug(Blog blog, IUpdateModel updater) {
|
|
_routableService.FillSlug(blog.As<RoutableAspect>());
|
|
|
|
|
|
if (string.IsNullOrEmpty(blog.Slug)) {
|
|
return;
|
|
|
|
// OR
|
|
|
|
// updater.AddModelError("Routable.Slug", T("The slug is required.").ToString());
|
|
// return;
|
|
}
|
|
|
|
|
|
if (!Regex.IsMatch(blog.Slug, @"^[^/:?#\[\]@!$&'()*+,;=\s]+$")) {
|
|
//todo: (heskew) get rid of the hard-coded prefix
|
|
updater.AddModelError("Routable.Slug", T("Please do not use any of the following characters in your slugs: \"/\", \":\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\". No spaces are allowed (please use dashes or underscores instead).").ToString());
|
|
}
|
|
|
|
var slugsLikeThis = _blogService.Get().Where(
|
|
b => b.Slug.StartsWith(blog.Slug, StringComparison.OrdinalIgnoreCase) &&
|
|
b.Id != blog.Id).Select(b => b.Slug);
|
|
|
|
//todo: (heskew) need better messages
|
|
if (slugsLikeThis.Count() > 0) {
|
|
var originalSlug = blog.Slug;
|
|
//todo: (heskew) make auto-uniqueness optional
|
|
blog.Slug = _routableService.GenerateUniqueSlug(blog.Slug, slugsLikeThis);
|
|
|
|
if (originalSlug != blog.Slug)
|
|
_orchardServices.Notifier.Warning(T("Slugs in conflict. \"{0}\" is already set for a previously created blog so this blog now has the slug \"{1}\"",
|
|
originalSlug, blog.Slug));
|
|
}
|
|
}
|
|
}
|
|
}
|