mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Hooked up everything for blog archives. Currently no UI to point to it though. Not sure how we're going to do that without widgets. Maybe with a hardcoded action filter for now?
--HG-- extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4045086
This commit is contained in:
@@ -7,7 +7,6 @@ using Orchard.Blogs.ViewModels;
|
||||
using Orchard.Data;
|
||||
using Orchard.Localization;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Mvc.Results;
|
||||
using Orchard.Security;
|
||||
using Orchard.UI.Notify;
|
||||
|
@@ -66,7 +66,7 @@ namespace Orchard.Blogs.Controllers {
|
||||
|
||||
return Combined(
|
||||
ContentItemTemplate("Items/Blogs.Blog").LongestMatch(displayType, "Summary", "DetailAdmin", "SummaryAdmin"),
|
||||
blogPosts == null ? null : ContentPartTemplate(blogPosts, "Parts/Blogs.BlogPost.List", "").Location("body"));
|
||||
blogPosts == null ? null : ContentPartTemplate(blogPosts, "Parts/Blogs.BlogPost.List", "").Location("primary"));
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(Blog blog) {
|
||||
|
@@ -1,3 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Blogs.Extensions;
|
||||
@@ -46,6 +47,7 @@ namespace Orchard.Blogs.Controllers {
|
||||
if (!_authorizer.Authorize(Permissions.ViewPost, T("Couldn't view blog post")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
//TODO: (erikpo) Move looking up the current blog up into a modelbinder
|
||||
Blog blog = _blogService.Get(blogSlug);
|
||||
|
||||
if (blog == null)
|
||||
@@ -64,9 +66,27 @@ namespace Orchard.Blogs.Controllers {
|
||||
return View(model);
|
||||
}
|
||||
|
||||
public ActionResult ListByArchive(string blogSlug, string archiveData) {
|
||||
//TODO: (erikpo) Move looking up the current blog up into a modelbinder
|
||||
Blog blog = _blogService.Get(blogSlug);
|
||||
|
||||
if (blog == null)
|
||||
return new NotFoundResult();
|
||||
|
||||
var archive = new ArchiveData(archiveData);
|
||||
var model = new BlogPostArchiveViewModel {
|
||||
Blog = blog,
|
||||
ArchiveData = archive,
|
||||
BlogPosts = _blogPostService.Get(blog, archive).Select(b => _contentManager.BuildDisplayModel(b, "Summary"))
|
||||
};
|
||||
|
||||
return View(model);
|
||||
}
|
||||
|
||||
public ActionResult Slugify(string value) {
|
||||
string slug = value;
|
||||
|
||||
//TODO: (erikpo) Move this into a utility class
|
||||
if (!string.IsNullOrEmpty(value)) {
|
||||
Regex regex = new Regex("([^a-z0-9-_]?)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
|
@@ -14,6 +14,18 @@ namespace Orchard.Blogs.Extensions {
|
||||
return urlHelper.Action("Item", "Blog", new {blogSlug, area = "Orchard.Blogs"});
|
||||
}
|
||||
|
||||
public static string BlogArchiveYear(this UrlHelper urlHelper, string blogSlug, int year) {
|
||||
return urlHelper.Action("ListByArchive", "BlogPost", new { blogSlug, archiveData = year.ToString(), area = "Orchard.Blogs" });
|
||||
}
|
||||
|
||||
public static string BlogArchiveMonth(this UrlHelper urlHelper, string blogSlug, int year, int month) {
|
||||
return urlHelper.Action("ListByArchive", "BlogPost", new { blogSlug, archiveData = string.Format("{0}/{1}", year, month), area = "Orchard.Blogs" });
|
||||
}
|
||||
|
||||
public static string BlogArchiveDay(this UrlHelper urlHelper, string blogSlug, int year, int month, int day) {
|
||||
return urlHelper.Action("ListByArchive", "BlogPost", new {blogSlug, archiveData = string.Format("{0}/{1}/{2}", year, month, day), area = "Orchard.Blogs"});
|
||||
}
|
||||
|
||||
public static string BlogForAdmin(this UrlHelper urlHelper, string blogSlug) {
|
||||
return urlHelper.Action("Item", "BlogAdmin", new {blogSlug, area = "Orchard.Blogs"});
|
||||
}
|
||||
|
125
src/Orchard.Web/Packages/Orchard.Blogs/Models/ArchiveData.cs
Normal file
125
src/Orchard.Web/Packages/Orchard.Blogs/Models/ArchiveData.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Orchard.Blogs.Models {
|
||||
public class ArchiveData : IEquatable<ArchiveData>, IComparable<ArchiveData> {
|
||||
private static readonly string _defaultString = DateTime.Now.Year.ToString();
|
||||
|
||||
private static readonly Regex archiveDataRegex =
|
||||
new Regex(@"^(?<year>\d{4})(?:/(?<month>\d{1,2})?(?:/(?<day>\d{1,2})?)?)?(?:/(?:page(?<page>\d+))?)?$",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
public ArchiveData(string rawData) {
|
||||
if (!string.IsNullOrEmpty(rawData)) {
|
||||
Match archiveDataMatch = archiveDataRegex.Match(rawData);
|
||||
|
||||
int year;
|
||||
if (archiveDataMatch.Groups["year"].Success &&
|
||||
int.TryParse(archiveDataMatch.Groups["year"].Value, out year)) {
|
||||
Year = year;
|
||||
}
|
||||
|
||||
int month;
|
||||
if (archiveDataMatch.Groups["month"].Success &&
|
||||
int.TryParse(archiveDataMatch.Groups["month"].Value, out month)) {
|
||||
Month = month;
|
||||
}
|
||||
|
||||
int day;
|
||||
if (archiveDataMatch.Groups["day"].Success &&
|
||||
int.TryParse(archiveDataMatch.Groups["day"].Value, out day)) {
|
||||
Day = day;
|
||||
}
|
||||
|
||||
int page;
|
||||
if (archiveDataMatch.Groups["page"].Success &&
|
||||
int.TryParse(archiveDataMatch.Groups["page"].Value, out page)) {
|
||||
Page = page;
|
||||
}
|
||||
else {
|
||||
Page = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Page { get; private set; }
|
||||
public int Year { get; private set; }
|
||||
public int Month { get; private set; }
|
||||
public int Day { get; private set; }
|
||||
|
||||
public static string DefaultString {
|
||||
get { return _defaultString; }
|
||||
}
|
||||
|
||||
#region IComparable<ArchiveData> Members
|
||||
|
||||
public int CompareTo(ArchiveData other) {
|
||||
return ToDateTime().CompareTo(other.ToDateTime());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEquatable<ArchiveData> Members
|
||||
|
||||
public bool Equals(ArchiveData other) {
|
||||
if (other != null) {
|
||||
return Day == other.Day && Month == other.Month && Page == other.Page && Year == other.Year;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override string ToString() {
|
||||
var sb = new StringBuilder();
|
||||
|
||||
if (Year > 0) {
|
||||
sb.AppendFormat("{0}/", Year);
|
||||
}
|
||||
|
||||
if (Month > 0) {
|
||||
sb.AppendFormat("{0}/", Month);
|
||||
}
|
||||
|
||||
if (Day > 0) {
|
||||
sb.AppendFormat("{0}/", Day);
|
||||
}
|
||||
|
||||
if (Page > 1) {
|
||||
sb.AppendFormat("page{0}/", Page);
|
||||
}
|
||||
|
||||
return sb.Remove(sb.Length - 1, 1).ToString();
|
||||
}
|
||||
|
||||
public DateTime ToDateTime() {
|
||||
int projectedYear = DateTime.MinValue.Year, projectedMonth = 1, projectedDay = 1;
|
||||
|
||||
if (Year > 0) {
|
||||
projectedYear = Year;
|
||||
}
|
||||
if (Month > 0) {
|
||||
projectedMonth = Month;
|
||||
}
|
||||
if (Day > 0) {
|
||||
projectedDay = Day;
|
||||
}
|
||||
|
||||
return new DateTime(projectedYear, projectedMonth, projectedDay);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) {
|
||||
if (obj is ArchiveData) {
|
||||
return Equals(obj as ArchiveData);
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return ToDateTime().GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
@@ -81,7 +81,9 @@
|
||||
<Compile Include="Extensions\HtmlHelperExtensions.cs" />
|
||||
<Compile Include="Extensions\UriExtensions.cs" />
|
||||
<Compile Include="Extensions\UrlHelperExtensions.cs" />
|
||||
<Compile Include="Models\ArchiveData.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
<Compile Include="Routing\IsArchiveConstraint.cs" />
|
||||
<Compile Include="Routing\IsBlogConstraint.cs" />
|
||||
<Compile Include="Services\BlogService.cs" />
|
||||
<Compile Include="Controllers\BlogController.cs" />
|
||||
@@ -97,6 +99,7 @@
|
||||
<Compile Include="Services\IBlogPostService.cs" />
|
||||
<Compile Include="Services\IBlogService.cs" />
|
||||
<Compile Include="ViewModels\AdminBlogsViewModel.cs" />
|
||||
<Compile Include="ViewModels\BlogPostArchiveViewModel.cs" />
|
||||
<Compile Include="ViewModels\BlogViewModel.cs" />
|
||||
<Compile Include="ViewModels\BlogPostViewModel.cs" />
|
||||
<Compile Include="ViewModels\BlogPostEditViewModel.cs" />
|
||||
@@ -110,6 +113,7 @@
|
||||
<Content Include="Package.txt" />
|
||||
<Content Include="Views\BlogPost\Create.ascx" />
|
||||
<Content Include="Views\BlogPost\Edit.ascx" />
|
||||
<Content Include="Views\BlogPost\ListByArchive.ascx" />
|
||||
<Content Include="Views\DisplayTemplates\Items\Blogs.Blog.DetailAdmin.ascx" />
|
||||
<Content Include="Views\BlogAdmin\Item.ascx" />
|
||||
<Content Include="Views\DisplayTemplates\Items\Blogs.Blog.SummaryAdmin.ascx" />
|
||||
|
@@ -189,6 +189,23 @@ namespace Orchard.Blogs {
|
||||
},
|
||||
new MvcRouteHandler())
|
||||
},
|
||||
new RouteDescriptor {
|
||||
Route = new Route(
|
||||
"{blogSlug}/Archive/{*archiveData}",
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Blogs"},
|
||||
{"controller", "BlogPost"},
|
||||
{"action", "ListByArchive"}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"blogSlug", new IsBlogConstraint(_containerProvider)},
|
||||
{"archiveData", new IsArchiveConstraint()}
|
||||
},
|
||||
new RouteValueDictionary {
|
||||
{"area", "Orchard.Blogs"}
|
||||
},
|
||||
new MvcRouteHandler())
|
||||
},
|
||||
new RouteDescriptor {
|
||||
Route = new Route(
|
||||
"{blogSlug}/{postSlug}",
|
||||
|
@@ -0,0 +1,12 @@
|
||||
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) {
|
||||
return values[parameterName] != null && (new ArchiveData(values[parameterName].ToString())).Year > 0;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Blogs.Models;
|
||||
@@ -16,21 +17,37 @@ namespace Orchard.Blogs.Services {
|
||||
}
|
||||
|
||||
public BlogPost Get(Blog blog, string slug) {
|
||||
return _contentManager.Query<BlogPost, BlogPostRecord >()
|
||||
.Join<RoutableRecord>().Where(rr => rr.Slug == slug)
|
||||
.Join<CommonRecord>().Where(cr => cr.Container == blog.Record.ContentItemRecord)
|
||||
.List().FirstOrDefault();
|
||||
return
|
||||
_contentManager.Query<BlogPost, BlogPostRecord>().Join<RoutableRecord>().Where(rr => rr.Slug == slug).
|
||||
Join<CommonRecord>().Where(cr => cr.Container == blog.Record.ContentItemRecord).List().
|
||||
SingleOrDefault();
|
||||
}
|
||||
|
||||
public IEnumerable<BlogPost> Get(Blog blog) {
|
||||
return _contentManager.Query<BlogPost, BlogPostRecord>()
|
||||
.Join<CommonRecord>().Where(cr => cr.Container == blog.Record.ContentItemRecord)
|
||||
.OrderByDescending(cr => cr.CreatedUtc)
|
||||
.List();
|
||||
return GetBlogQuery(blog).List();
|
||||
}
|
||||
|
||||
public IEnumerable<BlogPost> Get(Blog blog, ArchiveData archiveData) {
|
||||
var query = GetBlogQuery(blog);
|
||||
|
||||
if (archiveData.Day > 0)
|
||||
query = query.Where(cr => cr.CreatedUtc >= new DateTime(archiveData.Year, archiveData.Month, archiveData.Day) && cr.CreatedUtc < new DateTime(archiveData.Year, archiveData.Month, archiveData.Day + 1));
|
||||
else if (archiveData.Month > 0)
|
||||
query = query.Where(cr => cr.CreatedUtc >= new DateTime(archiveData.Year, archiveData.Month, 1) && cr.CreatedUtc < new DateTime(archiveData.Year, archiveData.Month + 1, 1));
|
||||
else
|
||||
query = query.Where(cr => cr.CreatedUtc >= new DateTime(archiveData.Year, 1, 1) && cr.CreatedUtc < new DateTime(archiveData.Year + 1, 1, 1));
|
||||
|
||||
return query.List();
|
||||
}
|
||||
|
||||
public void Delete(BlogPost blogPost) {
|
||||
_blogPostRepository.Delete(blogPost.Record);
|
||||
}
|
||||
|
||||
private IContentQuery<BlogPost, CommonRecord> GetBlogQuery(Blog blog) {
|
||||
return
|
||||
_contentManager.Query<BlogPost, BlogPostRecord>().Join<CommonRecord>().Where(
|
||||
cr => cr.Container == blog.Record.ContentItemRecord).OrderByDescending(cr => cr.CreatedUtc);
|
||||
}
|
||||
}
|
||||
}
|
@@ -5,6 +5,7 @@ namespace Orchard.Blogs.Services {
|
||||
public interface IBlogPostService : IDependency {
|
||||
BlogPost Get(Blog blog, string slug);
|
||||
IEnumerable<BlogPost> Get(Blog blog);
|
||||
IEnumerable<BlogPost> Get(Blog blog, ArchiveData archiveData);
|
||||
void Delete(BlogPost blogPost);
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.Blogs.Models;
|
||||
using Orchard.Mvc.ViewModels;
|
||||
|
||||
namespace Orchard.Blogs.ViewModels {
|
||||
public class BlogPostArchiveViewModel : BaseViewModel {
|
||||
public Blog Blog { get; set; }
|
||||
public ArchiveData ArchiveData { get; set; }
|
||||
public IEnumerable<ContentItemViewModel<BlogPost>> BlogPosts { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<BlogPostArchiveViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Blogs.Extensions"%>
|
||||
<%@ Import Namespace="Orchard.Blogs.ViewModels"%>
|
||||
<h1><%=Html.TitleForPage(T("Archives").ToString(), Model.ArchiveData.Year.ToString(), Model.ArchiveData.Month > 0 ? new DateTime(Model.ArchiveData.Year, Model.ArchiveData.Month, 1).ToString("MMMM") : null, Model.ArchiveData.Day > 0 ? Model.ArchiveData.Day.ToString() : null)%></h1>
|
||||
<%=T("Archives").ToString()
|
||||
%> / <%=Html.Link(Model.ArchiveData.Year.ToString(), Url.BlogArchiveYear(Model.Blog.Slug, Model.ArchiveData.Year))
|
||||
%><%=Model.ArchiveData.Month > 0 ? string.Format(" / {0}", Html.Link(Model.ArchiveData.ToDateTime().ToString("MMMM"), Url.BlogArchiveMonth(Model.Blog.Slug, Model.ArchiveData.Year, Model.ArchiveData.Month))) : ""
|
||||
%><%=Model.ArchiveData.Day > 0 ? string.Format(" / {0}", Html.Link(Model.ArchiveData.Day.ToString(), Url.BlogArchiveDay(Model.Blog.Slug, Model.ArchiveData.Year, Model.ArchiveData.Month, Model.ArchiveData.Day))) : ""
|
||||
%>
|
||||
<%=Html.UnorderedList(Model.BlogPosts, (c, i) => Html.DisplayForItem(c).ToHtmlString(), "blogPosts contentItems")%>
|
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Orchard.Extensions;
|
||||
using Orchard.Mvc.Html;
|
||||
using Orchard.Themes;
|
||||
|
Reference in New Issue
Block a user