mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-01-22 21:02:08 +08:00
bug fixes
* Display comment count in blog post (admin and front-end). * In admin, also display # of pending comments. * In admin, both comment count and pending count are hyperlinks to the "manage comments" page for the blog post. * Fix a few incorrect redirect calls in the comments module * Removed fake comment count display for aggregate blog view (we will resurrect it later with a correct implementation) --HG-- extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4045823
This commit is contained in:
@@ -9,9 +9,11 @@ if (Model.Entries.Count() > 0) { %>
|
||||
// Add blog post count rendering into "meta" zone
|
||||
entry.ContentItemViewModel.Zones.AddAction("meta", html => {
|
||||
int draftCount = entry.TotalPostCount - entry.ContentItemViewModel.Item.PostCount;
|
||||
int publishedCount = entry.TotalPostCount;
|
||||
int totalPostCount = entry.TotalPostCount;
|
||||
var draftText = (draftCount == 0 ? "": string.Format(" ({0} draft{1})", draftCount, draftCount == 1 ? "" : "s"));
|
||||
var linkContent = _Encoded("{0} post{1}{2}", publishedCount, publishedCount == 1 ? "" : "s", draftText);
|
||||
|
||||
var linkContent = _Encoded("{0} post{1}{2}", totalPostCount, totalPostCount == 1 ? "" : "s", draftText);
|
||||
|
||||
html.ViewContext.Writer.Write(html.Link(linkContent.ToString(), Url.BlogForAdmin(entry.ContentItemViewModel.Item.Slug)));
|
||||
});
|
||||
|
||||
|
||||
@@ -3,10 +3,7 @@
|
||||
<%@ Import Namespace="Orchard.Blogs.Extensions"%>
|
||||
<%@ Import Namespace="Orchard.Blogs.Models"%>
|
||||
<h2><%=Html.Link(Html.Encode(Model.Item.Name), Url.BlogForAdmin(Model.Item.Slug)) %></h2>
|
||||
<div class="meta">
|
||||
<%Html.Zone("meta"); %>
|
||||
| <%=Html.Link(_Encoded("?? comments").ToString(), "") %>
|
||||
</div>
|
||||
<div class="meta"><%Html.Zone("meta");%></div>
|
||||
<%--<p>[list of authors] [modify blog access]</p>--%>
|
||||
<p><%=Html.Encode(Model.Item.Description) %></p>
|
||||
<ul class="actions">
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace Orchard.Comments.Controllers {
|
||||
}
|
||||
catch (Exception exception) {
|
||||
_notifier.Error(T("Editing comments failed: " + exception.Message));
|
||||
return Index(viewModel.Options);
|
||||
return RedirectToAction("Index", "Admin", new { options = viewModel.Options });
|
||||
}
|
||||
|
||||
return RedirectToAction("Index");
|
||||
@@ -187,7 +187,7 @@ namespace Orchard.Comments.Controllers {
|
||||
var model = new CommentsDetailsViewModel {
|
||||
Comments = entries,
|
||||
Options = options,
|
||||
DisplayNameForCommentedItem = _commentService.GetDisplayForCommentedContent(id).DisplayText,
|
||||
DisplayNameForCommentedItem = _commentService.GetDisplayForCommentedContent(id) == null ? "" : _commentService.GetDisplayForCommentedContent(id).DisplayText,
|
||||
CommentedItemId = id,
|
||||
CommentsClosedOnItem = _commentService.CommentsClosedForCommentedContent(id),
|
||||
};
|
||||
@@ -195,7 +195,7 @@ namespace Orchard.Comments.Controllers {
|
||||
}
|
||||
catch (Exception exception) {
|
||||
_notifier.Error(T("Listing comments failed: " + exception.Message));
|
||||
return Index(new CommentIndexOptions());
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ namespace Orchard.Comments.Controllers {
|
||||
}
|
||||
catch (Exception exception) {
|
||||
_notifier.Error(T("Editing comment failed: " + exception.Message));
|
||||
return Index(new CommentIndexOptions());
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ namespace Orchard.Comments.Controllers {
|
||||
if (!String.IsNullOrEmpty(returnUrl)) {
|
||||
return Redirect(returnUrl);
|
||||
}
|
||||
return Index(new CommentIndexOptions());
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Mvc.Html;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Mvc.Html;
|
||||
|
||||
namespace Orchard.Comments.Extensions {
|
||||
public static class HtmlHelperExtensions {
|
||||
public static MvcHtmlString CommentSummaryLinks(this HtmlHelper html, Localizer T, ContentItem item, int commentCount, int pendingCount) {
|
||||
string commentText = "";
|
||||
|
||||
if (item.Id != 0) {
|
||||
if (commentCount == 0) {
|
||||
commentText += html.Encode(T("no comments"));
|
||||
}
|
||||
else {
|
||||
commentText +=
|
||||
html.ActionLink(
|
||||
T("{0} comment{1}", commentCount, commentCount == 1 ? "" : "s").ToString(),
|
||||
"Details",
|
||||
new {
|
||||
Area = "Orchard.Comments",
|
||||
Controller = "Admin",
|
||||
id = item.Id,
|
||||
returnUrl = html.ViewContext.HttpContext.Request.Url
|
||||
});
|
||||
}
|
||||
|
||||
if (pendingCount > 0) {
|
||||
commentText += " - ";
|
||||
commentText += html.ActionLink(T("{0} pending", pendingCount).ToString(),
|
||||
"Details",
|
||||
new {
|
||||
Area = "Orchard.Comments",
|
||||
Controller = "Admin",
|
||||
id = item.Id,
|
||||
returnUrl = html.ViewContext.HttpContext.Request.Url
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return MvcHtmlString.Create(commentText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.Comments.Services;
|
||||
using Orchard.Data;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
|
||||
namespace Orchard.Comments.Models {
|
||||
[UsedImplicitly]
|
||||
public class HasCommentsHandler : ContentHandler {
|
||||
public HasCommentsHandler(
|
||||
IRepository<Comment> commentsRepository,
|
||||
IRepository<HasCommentsRecord> hasCommentsRepository,
|
||||
ICommentService commentService) {
|
||||
|
||||
Filters.Add(new ActivatingFilter<HasComments>("sandboxpage"));
|
||||
Filters.Add(new ActivatingFilter<HasComments>("blogpost"));
|
||||
Filters.Add(new StorageFilter<HasCommentsRecord>(hasCommentsRepository) );
|
||||
|
||||
OnActivated<HasComments>((ctx, x) => {
|
||||
x.CommentsActive = true;
|
||||
x.CommentsShown = true;
|
||||
});
|
||||
|
||||
OnLoading<HasComments>((context, comments) => {
|
||||
comments.Comments = commentsRepository.Fetch(x => x.CommentedOn == context.ContentItem.Id && x.Status == CommentStatus.Approved);
|
||||
});
|
||||
|
||||
OnRemoved<HasComments>((context, c) => {
|
||||
if (context.ContentType == "blogpost" || context.ContentType == "sandboxpage") {
|
||||
//TODO: (erikpo) Once comments are content items, replace the following repository delete call to a content manager remove call
|
||||
commentService.GetCommentsForCommentedContent(context.ContentItem.Id).ToList().ForEach(
|
||||
commentsRepository.Delete);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,15 @@ using Orchard.ContentManagement.Records;
|
||||
|
||||
namespace Orchard.Comments.Models {
|
||||
public class HasComments : ContentPart<HasCommentsRecord> {
|
||||
public HasComments() {
|
||||
Comments = new List<Comment>();
|
||||
PendingComments = new List<Comment>();
|
||||
}
|
||||
|
||||
public int CommentCount { get { return Comments.Count(); } }
|
||||
public int CommentCount { get { return Comments.Count; } }
|
||||
|
||||
public IEnumerable<Comment> Comments { get; set; }
|
||||
public IList<Comment> Comments { get; set; }
|
||||
public IList<Comment> PendingComments { get; set; }
|
||||
|
||||
public bool CommentsShown {
|
||||
get { return Record.CommentsShown; }
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using Orchard.Comments.Models;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.Comments.ViewModels;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
|
||||
namespace Orchard.Comments.Controllers {
|
||||
namespace Orchard.Comments.Models {
|
||||
[UsedImplicitly]
|
||||
public class HasCommentsDriver : ContentPartDriver<HasComments> {
|
||||
protected override DriverResult Display(HasComments part, string displayType) {
|
||||
if (part.CommentsShown == false) {
|
||||
@@ -17,12 +19,18 @@ namespace Orchard.Comments.Controllers {
|
||||
// ContentPartTemplate(part, "Parts/Comments.HasComments").Location("body", "below.5"));
|
||||
return ContentPartTemplate(part, "Parts/Comments.HasComments").Location("primary", "after.5");
|
||||
}
|
||||
|
||||
if (displayType.Contains("Summary")) {
|
||||
return ContentPartTemplate(part, "Parts/Comments.Count").Location("meta");
|
||||
else if (displayType == "SummaryAdmin") {
|
||||
var model = new CommentCountViewModel(part);
|
||||
return ContentPartTemplate(model, "Parts/Comments.CountAdmin").Location("meta");
|
||||
}
|
||||
else if (displayType.Contains("Summary")) {
|
||||
var model = new CommentCountViewModel(part);
|
||||
return ContentPartTemplate(model, "Parts/Comments.Count").Location("meta");
|
||||
}
|
||||
else {
|
||||
var model = new CommentCountViewModel(part);
|
||||
return ContentPartTemplate(model, "Parts/Comments.Count").Location("primary", "before.5");
|
||||
}
|
||||
|
||||
return ContentPartTemplate(part, "Parts/Comments.Count").Location("primary", "before.5");
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(HasComments part) {
|
||||
@@ -0,0 +1,65 @@
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.Comments.Services;
|
||||
using Orchard.Data;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
|
||||
namespace Orchard.Comments.Models {
|
||||
[UsedImplicitly]
|
||||
public class HasCommentsHandler : ContentHandler {
|
||||
public HasCommentsHandler(
|
||||
IRepository<Comment> commentsRepository,
|
||||
IRepository<HasCommentsRecord> hasCommentsRepository,
|
||||
ICommentService commentService) {
|
||||
|
||||
Filters.Add(new ActivatingFilter<HasComments>("sandboxpage"));
|
||||
Filters.Add(new ActivatingFilter<HasComments>("blogpost"));
|
||||
Filters.Add(new StorageFilter<HasCommentsRecord>(hasCommentsRepository));
|
||||
|
||||
OnActivated<HasComments>((ctx, x) => {
|
||||
x.CommentsActive = true;
|
||||
x.CommentsShown = true;
|
||||
});
|
||||
|
||||
OnLoading<HasComments>((context, comments) => {
|
||||
comments.Comments = commentsRepository.Fetch(x => x.CommentedOn == context.ContentItem.Id && x.Status == CommentStatus.Approved).ToList();
|
||||
comments.PendingComments = commentsRepository.Fetch(x => x.CommentedOn == context.ContentItem.Id && x.Status == CommentStatus.Pending).ToList();
|
||||
});
|
||||
|
||||
OnRemoved<HasComments>((context, c) => {
|
||||
//TODO: (erikpo) Once comments are content items, replace the following repository delete call to a content manager remove call
|
||||
var comments = commentService.GetCommentsForCommentedContent(context.ContentItem.Id).ToList();
|
||||
comments.ForEach(commentsRepository.Delete);
|
||||
});
|
||||
}
|
||||
}
|
||||
#if false
|
||||
[UsedImplicitly]
|
||||
public class HasCommentsContainerHandler : ContentHandler {
|
||||
public HasCommentsContainerHandler() {
|
||||
Filters.Add(new ActivatingFilter<HasCommentsContainer>("blog"));
|
||||
}
|
||||
}
|
||||
|
||||
public class HasCommentsContainer : ContentPart {
|
||||
}
|
||||
|
||||
public class HasCommentsContainerDriver : ContentPartDriver<HasCommentsContainer> {
|
||||
protected override DriverResult Display(HasCommentsContainer part, string displayType) {
|
||||
if (displayType.Contains("Summary")) {
|
||||
// Find all contents item with this part as the container
|
||||
var parts = part.ContentItem.ContentManager.Query()
|
||||
.Where<CommonRecord>(rec => rec.Container == part.ContentItem.Record).List();
|
||||
|
||||
// Count comments and create template
|
||||
int count = parts.Aggregate(0, (seed, item) => item.Has<HasComments>() ? item.As<HasComments>().CommentCount : 0);
|
||||
|
||||
var model = new CommentCountViewModel { Item = part.ContentItem, CommentCount = count };
|
||||
return ContentPartTemplate(model, "Parts/Comments.Count").Location("meta");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -67,15 +67,17 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="AdminMenu.cs" />
|
||||
<Compile Include="Controllers\AdminController.cs" />
|
||||
<Compile Include="Controllers\HasCommentsDriver.cs" />
|
||||
<Compile Include="Extensions\HtmlHelperExtensions.cs" />
|
||||
<Compile Include="Models\HasCommentsDriver.cs" />
|
||||
<Compile Include="Feeds\CommentedOnContainerFeedQuery.cs" />
|
||||
<Compile Include="Feeds\CommentedOnFeedQuery.cs" />
|
||||
<Compile Include="Feeds\CommentFeedItemBuilder.cs" />
|
||||
<Compile Include="Models\Comment.cs" />
|
||||
<Compile Include="ViewModels\CommentCountViewModel.cs" />
|
||||
<Compile Include="Models\CommentSettings.cs" />
|
||||
<Compile Include="Models\CommentSettingsHandler.cs" />
|
||||
<Compile Include="Models\CommentSettingsRecord.cs" />
|
||||
<Compile Include="Models\CommentsHandler.cs" />
|
||||
<Compile Include="Models\HasCommentsHandler.cs" />
|
||||
<Compile Include="Models\HasComments.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
@@ -95,6 +97,7 @@
|
||||
<Content Include="Views\Admin\Index.aspx" />
|
||||
<Content Include="Views\DisplayTemplates\Parts\Comments.HasComments.ascx" />
|
||||
<Content Include="Views\DisplayTemplates\Parts\Comments.Count.ascx" />
|
||||
<Content Include="Views\DisplayTemplates\Parts\Comments.CountAdmin.ascx" />
|
||||
<Content Include="Views\EditorTemplates\Parts\Comments.SiteSettings.ascx" />
|
||||
<Content Include="Views\EditorTemplates\Parts\Comments.HasComments.ascx" />
|
||||
<Content Include="Views\ListOfComments.ascx" />
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using Orchard.Comments.Models;
|
||||
using Orchard.ContentManagement;
|
||||
|
||||
namespace Orchard.Comments.ViewModels {
|
||||
public class CommentCountViewModel {
|
||||
public CommentCountViewModel(HasComments part) {
|
||||
Item = part.ContentItem;
|
||||
CommentCount = part.Comments.Count;
|
||||
PendingCount = part.PendingComments.Count;
|
||||
}
|
||||
|
||||
public ContentItem Item { get; set; }
|
||||
public int CommentCount { get; set; }
|
||||
public int PendingCount { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<HasComments>" %>
|
||||
<%@ Import Namespace="Orchard.Comments.Models"%>
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<CommentCountViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Comments.ViewModels"%>
|
||||
<span class="commentcount"><%=_Encoded("{0} Comment{1}", Model.CommentCount, Model.CommentCount == 1 ? "" : "s")%></span>
|
||||
@@ -0,0 +1,4 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<CommentCountViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Comments.Extensions"%>
|
||||
<%@ Import Namespace="Orchard.Comments.ViewModels"%>
|
||||
<span class="commentcount"><%=Html.CommentSummaryLinks(T, Model.Item, Model.CommentCount, Model.PendingCount)%></span>
|
||||
@@ -1,7 +1,7 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<HasComments>" %>
|
||||
<%@ Import Namespace="Orchard.Comments.Models"%>
|
||||
<h2 id="comments"><%=_Encoded("{0} Comment{1}", Model.CommentCount, Model.CommentCount == 1 ? "" : "s") %></h2><%
|
||||
if (Model.CommentCount > 0) { Html.RenderPartial("ListOfComments", Model.Comments); }
|
||||
<h2 id="comments"><%=_Encoded("{0} Comment{1}", Model.Comments.Count, Model.Comments.Count == 1 ? "" : "s")%></h2><%
|
||||
if (Model.Comments.Count > 0) { Html.RenderPartial("ListOfComments", Model.Comments); }
|
||||
if (Model.CommentsActive == false) { %>
|
||||
<p><%=_Encoded("Comments have been disabled for this content.") %></p><%
|
||||
} else { %>
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<HasComments>" %>
|
||||
<%@ Import Namespace="Orchard.Comments.Extensions"%>
|
||||
<%@ Import Namespace="Orchard.Localization" %>
|
||||
<%@ Import Namespace="Orchard.Comments.Models" %>
|
||||
<fieldset>
|
||||
<%-- todo: (heskew) pull the legend and put the link to the comments elsewhere? --%>
|
||||
<legend><%=Model.ContentItem.Id != 0
|
||||
? T("Comments {0} - <a href=\"#\">?? pending</a>", Html.ActionLink(
|
||||
T("{0} comment{1}", Model.CommentCount, Model.CommentCount == 1 ? "" : "s").ToString(),
|
||||
"Details",
|
||||
new { Area = "Orchard.Comments", Controller = "Admin", id = Model.ContentItem.Id, returnUrl = Context.Request.Url }))
|
||||
: T("Comments")%></legend>
|
||||
<%--
|
||||
<legend><%=_Encoded("Comments")%> <%=Html.CommentSummaryLinks(T, Model.ContentItem, Model.Comments.Count, Model.PendingComments.Count)%></legend>
|
||||
<%--
|
||||
todo: (heskew) can get into a weird state if this is disabled but comments are active so, yeah, comment settings on a content item need to be hashed out
|
||||
<%=Html.EditorFor(m => m.CommentsShown) %>
|
||||
<label class="forcheckbox" for="CommentsShown"><%=T("Comments are shown. Existing comments are displayed.") %></label>
|
||||
--%>
|
||||
<%=Html.EditorFor(m => m.CommentsActive) %>
|
||||
<label class="forcheckbox" for="CommentsActive"><%=T("Allow new comments") %></label>
|
||||
<span class="hint forcheckbox"><%=T("Enable to show the comment form. Disabling still allows the existing comments to be shown but does not allow the conversation to continue.")%></span>
|
||||
<label class="forcheckbox" for="CommentsActive">
|
||||
<%=T("Allow new comments") %></label> <span class="hint forcheckbox">
|
||||
<%=T("Enable to show the comment form. Disabling still allows the existing comments to be shown but does not allow the conversation to continue.")%></span>
|
||||
</fieldset>
|
||||
@@ -1,7 +1,7 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<HasComments>" %>
|
||||
<%@ Import Namespace="Orchard.Comments.Models"%>
|
||||
<h2 id="comments"><%=_Encoded("{0} Comment{1}", Model.CommentCount, Model.CommentCount == 1 ? "" : "s") %></h2><%
|
||||
if (Model.CommentCount > 0) { Html.RenderPartial("ListOfComments", Model.Comments); }
|
||||
<h2 id="comments"><%=_Encoded("{0} Comment{1}", Model.Comments.Count, Model.Comments.Count == 1 ? "" : "s")%></h2><%
|
||||
if (Model.Comments.Count > 0) { Html.RenderPartial("ListOfComments", Model.Comments); }
|
||||
if (Model.CommentsActive == false) { %>
|
||||
<p><%=_Encoded("Comments have been disabled for this content.") %></p><%
|
||||
} else { %>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<% if (blogPost.Creator != null) {
|
||||
%><div class="posted"><%=_Encoded("Posted by {0} {1}", blogPost.Creator.UserName, Html.PublishedWhen(blogPost))%></div><%
|
||||
} %>
|
||||
<%=Html.Link(T(hasComments.CommentCount == 1 ? "{0} comment" : "{0} comments", hasComments.CommentCount).ToString(), "#comments")%>
|
||||
<%=Html.Link(T(hasComments.Comments.Count == 1 ? "{0} comment" : "{0} comments", hasComments.Comments.Count).ToString(), "#comments")%>
|
||||
</div>
|
||||
<%=Html.DisplayFor(m => bodyViewModelModel, "Parts/Common.Body")%>
|
||||
<%=Html.DisplayFor(m => hasComments, "Parts/Comments.HasComments", "") %>
|
||||
Reference in New Issue
Block a user