From 1ea0489ba149ecc5352edf6f2128b2a3c4c8e8ae Mon Sep 17 00:00:00 2001 From: ErikPorter Date: Wed, 2 Dec 2009 00:50:38 +0000 Subject: [PATCH] Some more blog and commenting cleanup. --HG-- extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4042880 --- .../Extensions/HtmlHelperExtensions.cs | 4 +- .../Orchard.Blogs/Views/BlogPost/Item.aspx | 2 +- .../Models/CommentSettings.cs | 30 +----- .../Models/CommentSettingsProvider.cs | 21 +++++ .../Models/CommentSettingsRecord.cs | 12 +++ .../Models/CommentsHandler.cs | 9 -- .../Orchard.Comments/Models/HasComments.cs | 14 +++ .../Orchard.Comments/Orchard.Comments.csproj | 4 + .../Services/CommentValidator.cs | 4 - .../Services/ICommentValidator.cs | 7 ++ .../Models/DisplayTemplates/HasComments.ascx | 94 ++++++++++--------- src/Orchard/Mvc/Html/HtmlHelperExtensions.cs | 83 ++++++++++++++++ 12 files changed, 193 insertions(+), 91 deletions(-) create mode 100644 src/Orchard.Web/Packages/Orchard.Comments/Models/CommentSettingsProvider.cs create mode 100644 src/Orchard.Web/Packages/Orchard.Comments/Models/CommentSettingsRecord.cs create mode 100644 src/Orchard.Web/Packages/Orchard.Comments/Models/HasComments.cs create mode 100644 src/Orchard.Web/Packages/Orchard.Comments/Services/ICommentValidator.cs diff --git a/src/Orchard.Web/Packages/Orchard.Blogs/Extensions/HtmlHelperExtensions.cs b/src/Orchard.Web/Packages/Orchard.Blogs/Extensions/HtmlHelperExtensions.cs index d12c70fda..cc4edf0cd 100644 --- a/src/Orchard.Web/Packages/Orchard.Blogs/Extensions/HtmlHelperExtensions.cs +++ b/src/Orchard.Web/Packages/Orchard.Blogs/Extensions/HtmlHelperExtensions.cs @@ -1,5 +1,6 @@ using System.Web.Mvc; using Orchard.Blogs.Models; +using Orchard.Mvc.Html; namespace Orchard.Blogs.Extensions { public static class HtmlHelperExtensions { @@ -8,8 +9,7 @@ namespace Orchard.Blogs.Extensions { } public static string Published(this HtmlHelper htmlHelper, BlogPost blogPost) { - //TODO: (erikpo) Relative time instead would be nice. - return blogPost.Published.HasValue ? blogPost.Published.Value.ToString("{0:M d yyyy h:mm tt}") : "Draft"; + return htmlHelper.DateTime(blogPost.Published, "as a Draft"); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Blogs/Views/BlogPost/Item.aspx b/src/Orchard.Web/Packages/Orchard.Blogs/Views/BlogPost/Item.aspx index 6ffd0918f..a5827700c 100644 --- a/src/Orchard.Web/Packages/Orchard.Blogs/Views/BlogPost/Item.aspx +++ b/src/Orchard.Web/Packages/Orchard.Blogs/Views/BlogPost/Item.aspx @@ -10,7 +10,7 @@

<%=Html.Encode(Model.Post.Title) %>

diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentSettings.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentSettings.cs index 72c2b715a..aac45833c 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentSettings.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentSettings.cs @@ -1,34 +1,6 @@ -using Orchard.Data; -using Orchard.Models; -using Orchard.Models.Driver; -using Orchard.Models.Records; +using Orchard.Models; namespace Orchard.Comments.Models { public class CommentSettings : ContentPart { } - - public class CommentSettingsRecord : ContentPartRecord { - public virtual bool RequireLoginToAddComment { get; set; } - public virtual bool EnableCommentsOnPages { get; set; } - public virtual bool EnableCommentsOnPosts { get; set; } - public virtual bool EnableSpamProtection { get; set; } - public virtual string AkismetKey { get; set; } - public virtual string AkismetUrl { get; set; } - } - - public class CommentSettingsProvider : ContentProvider { - private readonly IRepository _commentSettingsRepository; - public CommentSettingsProvider(IRepository repository) { - _commentSettingsRepository = repository; - Filters.Add(new ActivatingFilter("site")); - Filters.Add(new StorageFilter(_commentSettingsRepository) { AutomaticallyCreateMissingRecord = true }); - Filters.Add(new TemplateFilterForRecord("CommentSettings")); - OnActivated(DefaultSettings); - } - - private static void DefaultSettings(ActivatedContentContext context, CommentSettings settings) { - settings.Record.EnableCommentsOnPages = true; - settings.Record.EnableCommentsOnPosts = true; - } - } } diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentSettingsProvider.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentSettingsProvider.cs new file mode 100644 index 000000000..9142fc17a --- /dev/null +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentSettingsProvider.cs @@ -0,0 +1,21 @@ +using Orchard.Data; +using Orchard.Models.Driver; + +namespace Orchard.Comments.Models { + public class CommentSettingsProvider : ContentProvider { + private readonly IRepository _commentSettingsRepository; + + public CommentSettingsProvider(IRepository repository) { + _commentSettingsRepository = repository; + Filters.Add(new ActivatingFilter("site")); + Filters.Add(new StorageFilter(_commentSettingsRepository) { AutomaticallyCreateMissingRecord = true }); + Filters.Add(new TemplateFilterForRecord("CommentSettings")); + OnActivated(DefaultSettings); + } + + private static void DefaultSettings(ActivatedContentContext context, CommentSettings settings) { + settings.Record.EnableCommentsOnPages = true; + settings.Record.EnableCommentsOnPosts = true; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentSettingsRecord.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentSettingsRecord.cs new file mode 100644 index 000000000..ddb8f0963 --- /dev/null +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentSettingsRecord.cs @@ -0,0 +1,12 @@ +using Orchard.Models.Records; + +namespace Orchard.Comments.Models { + public class CommentSettingsRecord : ContentPartRecord { + public virtual bool RequireLoginToAddComment { get; set; } + public virtual bool EnableCommentsOnPages { get; set; } + public virtual bool EnableCommentsOnPosts { get; set; } + public virtual bool EnableSpamProtection { get; set; } + public virtual string AkismetKey { get; set; } + public virtual string AkismetUrl { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentsHandler.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentsHandler.cs index 00831476e..43dee3356 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentsHandler.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/CommentsHandler.cs @@ -5,15 +5,6 @@ using Orchard.Models.Driver; using Orchard.UI.Models; namespace Orchard.Comments.Models { - public class HasComments : ContentPart { - public HasComments() { - Comments = new List(); - } - - public IEnumerable Comments { get; set; } - public bool Closed { get; set; } - } - public class HasCommentsProvider : ContentProvider { private readonly IRepository _commentsRepository; private readonly IRepository _closedCommentsRepository; diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Models/HasComments.cs b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasComments.cs new file mode 100644 index 000000000..883c60795 --- /dev/null +++ b/src/Orchard.Web/Packages/Orchard.Comments/Models/HasComments.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.Linq; +using Orchard.Models; + +namespace Orchard.Comments.Models { + public class HasComments : ContentPart { + public HasComments() { + Comments = Enumerable.Empty(); + } + + public IEnumerable Comments { get; set; } + public bool Closed { get; set; } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Orchard.Comments.csproj b/src/Orchard.Web/Packages/Orchard.Comments/Orchard.Comments.csproj index c9141c689..33f9090a0 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Orchard.Comments.csproj +++ b/src/Orchard.Web/Packages/Orchard.Comments/Orchard.Comments.csproj @@ -69,11 +69,15 @@ + + + + diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Services/CommentValidator.cs b/src/Orchard.Web/Packages/Orchard.Comments/Services/CommentValidator.cs index 923ce314c..69f865491 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Services/CommentValidator.cs +++ b/src/Orchard.Web/Packages/Orchard.Comments/Services/CommentValidator.cs @@ -9,10 +9,6 @@ using Orchard.UI.Notify; using Joel.Net; namespace Orchard.Comments.Services { - public interface ICommentValidator : IDependency { - bool ValidateComment(Comment comment); - } - //This uses an akismet api implementation from http://akismetapi.codeplex.com/ //Since the implementation is trivial, it may make sense to implement it to reduce dependencies. public class AkismetCommentValidator : ICommentValidator { diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Services/ICommentValidator.cs b/src/Orchard.Web/Packages/Orchard.Comments/Services/ICommentValidator.cs new file mode 100644 index 000000000..000df27d9 --- /dev/null +++ b/src/Orchard.Web/Packages/Orchard.Comments/Services/ICommentValidator.cs @@ -0,0 +1,7 @@ +using Orchard.Comments.Models; + +namespace Orchard.Comments.Services { + public interface ICommentValidator : IDependency { + bool ValidateComment(Comment comment); + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Packages/Orchard.Comments/Views/Models/DisplayTemplates/HasComments.ascx b/src/Orchard.Web/Packages/Orchard.Comments/Views/Models/DisplayTemplates/HasComments.ascx index 0dad7f76e..13ad5262c 100644 --- a/src/Orchard.Web/Packages/Orchard.Comments/Views/Models/DisplayTemplates/HasComments.ascx +++ b/src/Orchard.Web/Packages/Orchard.Comments/Views/Models/DisplayTemplates/HasComments.ascx @@ -1,49 +1,51 @@ <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> +<%@ Import Namespace="Orchard.Mvc.Html"%> <%@ Import Namespace="Orchard.Comments.Models"%> -

<%= Model.Comments.Count() %> Comments

-
    - <% foreach (var comment in Model.Comments) {%> -
  1. - <%= comment.CommentText %> -
  2. -
  3. - Posted by <%= comment.UserName %> on <%= comment.CommentDate %> -
  4. -
    - <% } %> -
-<% if (Model.Closed) { %> -

Comments have been disabled for this content.

-<% } else { %> +

<%=Model.Comments.Count() %> Comment<%=Model.Comments.Count() == 1 ? "" : "s" %>

<% + foreach (var comment in Model.Comments) { %> +
+
+

+ <%--TODO: (erikpo) Need to clean the name and url so nothing dangerous goes out--%> + <%=Html.LinkOrDefault(comment.UserName, comment.SiteName, new { rel = "nofollow" })%> + said
<%=Html.Link(Html.DateTime(comment.CommentDate), "#")%>
+

+
+

<%=comment.CommentText %>

+
+
<% + } + if (Model.Closed) { %> +

Comments have been disabled for this content.

<% + } + else { %> <% Html.BeginForm("Create", "Admin", new { area = "Orchard.Comments" }); %> - <%= Html.ValidationSummary() %> -
-

Add a Comment

-

Information

-
    -
  1. - <%= Html.Hidden("CommentedOn", Model.ContentItem.Id) %> - <%= Html.Hidden("ReturnUrl", Context.Request.Url) %> - - -
  2. -
  3. - - -
  4. -
  5. - - -
  6. -
  7. - - -
  8. -
  9. - -
  10. -
-
- <% Html.EndForm(); %> -<% } %> \ No newline at end of file +<%=Html.ValidationSummary() %> +
+

Add a Comment

+
    +
  1. + <%= Html.Hidden("CommentedOn", Model.ContentItem.Id) %> + <%= Html.Hidden("ReturnUrl", Context.Request.Url) %> + + +
  2. +
  3. + + +
  4. +
  5. + + +
  6. +
  7. + + +
  8. +
  9. + +
  10. +
+
+<% Html.EndForm(); %><% + } %> \ No newline at end of file diff --git a/src/Orchard/Mvc/Html/HtmlHelperExtensions.cs b/src/Orchard/Mvc/Html/HtmlHelperExtensions.cs index 82dde32d0..b157b1aca 100644 --- a/src/Orchard/Mvc/Html/HtmlHelperExtensions.cs +++ b/src/Orchard/Mvc/Html/HtmlHelperExtensions.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Linq.Expressions; using System.Text; using System.Web.Mvc; +using System.Web.Routing; using Orchard.Utility; namespace Orchard.Mvc.Html { @@ -84,5 +85,87 @@ namespace Orchard.Mvc.Html { #endregion + #region Format Date/Time + + //TODO: (erikpo) This method needs localized + public static string DateTime(this HtmlHelper htmlHelper, DateTime value) + { + TimeSpan time = System.DateTime.UtcNow - value; + + if (time.TotalDays > 7) + //TODO: (erikpo) This format should come from a site setting + return "at " + value.ToString("MMM d yyyy h:mm tt"); + if (time.TotalHours > 24) + return string.Format("{0} day{1} ago", time.Days, time.Days == 1 ? "" : "s"); + if (time.TotalMinutes > 60) + return string.Format("{0} hour{1} ago", time.Hours, time.Hours == 1 ? "" : "s"); + if (time.TotalSeconds > 60) + return string.Format("{0} minute{1} ago", time.Minutes, time.Minutes == 1 ? "" : "s"); + else if (time.TotalSeconds > 10) + return string.Format("{0} second{1} ago", time.Seconds, time.Seconds == 1 ? "" : "s"); + else + return "a moment ago"; + } + + public static string DateTime(this HtmlHelper htmlHelper, DateTime? value, string defaultIfNull) { + return value.HasValue ? htmlHelper.DateTime(value.Value) : defaultIfNull; + } + + #endregion + + #region Link + + public static string Link(this HtmlHelper htmlHelper, string linkContents, string href) + { + return htmlHelper.Link(linkContents, href, null); + } + + public static string Link(this HtmlHelper htmlHelper, string linkContents, string href, object htmlAttributes) + { + return htmlHelper.Link(linkContents, href, new RouteValueDictionary(htmlAttributes)); + } + + public static string Link(this HtmlHelper htmlHelper, string linkContents, string href, IDictionary htmlAttributes) + { + TagBuilder tagBuilder = new TagBuilder("a") + { + InnerHtml = linkContents + }; + tagBuilder.MergeAttributes(htmlAttributes); + tagBuilder.MergeAttribute("href", href); + return tagBuilder.ToString(TagRenderMode.Normal); + } + + #endregion + + #region LinkOrDefault + + public static string LinkOrDefault(this HtmlHelper htmlHelper, string linkContents, string href) + { + return htmlHelper.LinkOrDefault(linkContents, href, null); + } + + public static string LinkOrDefault(this HtmlHelper htmlHelper, string linkContents, string href, object htmlAttributes) + { + return htmlHelper.LinkOrDefault(linkContents, href, new RouteValueDictionary(htmlAttributes)); + } + + public static string LinkOrDefault(this HtmlHelper htmlHelper, string linkContents, string href, IDictionary htmlAttributes) + { + if (!string.IsNullOrEmpty(href)) + { + TagBuilder tagBuilder = new TagBuilder("a") + { + InnerHtml = linkContents + }; + tagBuilder.MergeAttributes(htmlAttributes); + tagBuilder.MergeAttribute("href", href); + linkContents = tagBuilder.ToString(TagRenderMode.Normal); + } + + return linkContents; + } + + #endregion } }