- Bringing the Comments module back.

--HG--
branch : dev
This commit is contained in:
Suha Can 2010-09-15 12:13:19 -07:00
parent 16df5c2955
commit 668f356331
30 changed files with 423 additions and 418 deletions

View File

@ -1,20 +1,10 @@
using JetBrains.Annotations;
using Orchard.Comments.Models;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
namespace Orchard.Comments.Drivers {
[UsedImplicitly]
public class CommentPartDriver : ContentItemDriver<CommentPart> {
public readonly static ContentType ContentType = new ContentType {
Name = "Comment",
DisplayName = "Comment"
};
protected override ContentType GetContentType() {
return ContentType;
}
protected override string Prefix { get { return ""; } }
public class CommentPartDriver : ContentPartDriver<CommentPart> {
protected override string Prefix { get { return "Comments"; } }
}
}

View File

@ -0,0 +1,25 @@
using Orchard.Comments.Models;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.Localization;
namespace Orchard.Comments.Drivers {
public class CommentSettingsPartDriver : ContentPartDriver<CommentSettingsPart> {
public CommentSettingsPartDriver() {
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
protected override string Prefix { get { return "CommentSettings"; } }
protected override DriverResult Editor(CommentSettingsPart part) {
return ContentPartTemplate(part.Record, "Parts/Comments.SiteSettings");
}
protected override DriverResult Editor(CommentSettingsPart part, IUpdateModel updater) {
updater.TryUpdateModel(part.Record, Prefix, null, null);
return Editor(part);
}
}
}

View File

@ -9,7 +9,6 @@ namespace Orchard.Comments.Handlers {
public CommentSettingsPartHandler(IRepository<CommentSettingsPartRecord> repository) {
Filters.Add(new ActivatingFilter<CommentSettingsPart>("Site"));
Filters.Add(StorageFilter.For(repository));
Filters.Add(new TemplateFilterForRecord<CommentSettingsPartRecord>("CommentSettingsPart", "Parts/Comments.SiteSettings"));
}
}
}

View File

@ -75,6 +75,7 @@
<Compile Include="DataMigrations\CommentsDataMigration.cs" />
<Compile Include="Drivers\CommentPartDriver.cs" />
<Compile Include="Drivers\CommentsContainerPartDriver.cs" />
<Compile Include="Drivers\CommentSettingsPartDriver.cs" />
<Compile Include="Drivers\CommentsPartDriver.cs" />
<Compile Include="Extensions\HtmlHelperExtensions.cs" />
<Compile Include="Models\ClosedCommentsRecord.cs" />
@ -108,15 +109,6 @@
</ItemGroup>
<ItemGroup>
<Content Include="Module.txt" />
<Content Include="Views\Admin\Details.aspx" />
<Content Include="Views\Admin\Edit.aspx" />
<Content Include="Views\Admin\Index.aspx" />
<Content Include="Views\DisplayTemplates\Parts\Comments.Comments.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.Comments.ascx" />
<Content Include="Views\ListOfComments.ascx" />
<Content Include="Web.config" />
<Content Include="Views\Web.config" />
</ItemGroup>
@ -130,6 +122,17 @@
<Name>Orchard.Core</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Views\Admin\Details.cshtml" />
<None Include="Views\Admin\Edit.cshtml" />
<None Include="Views\Admin\Index.cshtml" />
<None Include="Views\DisplayTemplates\Parts\Comments.Comments.cshtml" />
<None Include="Views\DisplayTemplates\Parts\Comments.Count.cshtml" />
<None Include="Views\DisplayTemplates\Parts\Comments.CountAdmin.cshtml" />
<None Include="Views\EditorTemplates\Parts\Comments.Comments.cshtml" />
<None Include="Views\EditorTemplates\Parts\Comments.SiteSettings.cshtml" />
<None Include="Views\ListOfComments.cshtml" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -72,7 +72,7 @@ namespace Orchard.Comments.Services {
}
public CommentPart CreateComment(CreateCommentContext context, bool moderateComments) {
var comment = _contentManager.Create<CommentPart>(CommentPartDriver.ContentType.Name);
var comment = _contentManager.Create<CommentPart>("Comment");
comment.Record.Author = context.Author;
comment.Record.CommentDateUtc = _clock.UtcNow;

View File

@ -1,8 +1,7 @@
using System.ComponentModel.DataAnnotations;
using Orchard.Mvc.ViewModels;
namespace Orchard.Comments.ViewModels {
public class CommentsCreateViewModel : BaseViewModel {
public class CommentsCreateViewModel {
[Required]
public string Name { get; set; }
public string Email { get; set; }

View File

@ -1,8 +1,7 @@
using System.Collections.Generic;
using Orchard.Mvc.ViewModels;
namespace Orchard.Comments.ViewModels {
public class CommentsDetailsViewModel : BaseViewModel {
public class CommentsDetailsViewModel {
public IList<CommentEntry> Comments { get; set; }
public CommentDetailsOptions Options { get; set; }
public string DisplayNameForCommentedItem { get; set; }

View File

@ -1,8 +1,7 @@
using Orchard.Mvc.ViewModels;
using Orchard.Comments.Models;
using Orchard.Comments.Models;
namespace Orchard.Comments.ViewModels {
public class CommentsEditViewModel : BaseViewModel {
public class CommentsEditViewModel {
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }

View File

@ -1,9 +1,8 @@
using System.Collections.Generic;
using Orchard.Comments.Models;
using Orchard.Mvc.ViewModels;
namespace Orchard.Comments.ViewModels {
public class CommentsIndexViewModel : BaseViewModel {
public class CommentsIndexViewModel {
public IList<CommentEntry> Comments { get; set; }
public CommentIndexOptions Options { get; set; }
}

View File

@ -1,122 +0,0 @@
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage<CommentsDetailsViewModel>" %>
<%@ Import Namespace="Orchard.Comments.Models"%>
<%@ Import Namespace="Orchard.Comments.ViewModels"%>
<h1><%: Html.TitleForPage(T("Comments for {0}", Model.DisplayNameForCommentedItem).ToString()) %></h1>
<div class="manage"><%
if (Model.CommentsClosedOnItem) {
using (Html.BeginFormAntiForgeryPost(Url.Action("Enable", new { commentedItemId = Model.CommentedItemId }), FormMethod.Post, new { @class = "inline" })) { %>
<fieldset>
<button type="submit" title="<%: T("Enable Comments") %>"><%: T("Enable Comments")%></button>
</fieldset><%
}
} else {
using (Html.BeginFormAntiForgeryPost(Url.Action("Close", new { commentedItemId = Model.CommentedItemId }), FormMethod.Post, new { @class = "inline" })) { %>
<fieldset>
<button type="submit" class="button primaryAction" title="<%: T("Close Comments") %>"><%: T("Close Comments")%></button>
</fieldset><%
}
} %>
</div>
<% using(Html.BeginFormAntiForgeryPost()) { %>
<%: Html.ValidationSummary() %>
<fieldset class="bulk-actions">
<label for="publishActions"><%: T("Actions:") %></label>
<select id="publishActions" name="<%: Html.NameOf(m => m.Options.BulkAction)%>">
<%: Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.None, T("Choose action...").ToString())%>
<%: Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.Approve, T("Approve").ToString())%>
<%: Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.Pend, T("Pend").ToString())%>
<%: Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.MarkAsSpam, T("Mark as Spam").ToString())%>
<%: Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.Delete, T("Remove").ToString())%>
</select>
<input class="button" type="submit" name="submit.BulkEdit" value="<%: T("Apply") %>" />
</fieldset>
<fieldset class="bulk-actions">
<label for="filterResults"><%: T("Filter:")%></label>
<select id="filterResults" name="<%: Html.NameOf(m => m.Options.Filter)%>">
<%: Html.SelectOption(Model.Options.Filter, CommentDetailsFilter.All, T("All Comments").ToString())%>
<%: Html.SelectOption(Model.Options.Filter, CommentDetailsFilter.Approved, T("Approved Comments").ToString())%>
<%: Html.SelectOption(Model.Options.Filter, CommentDetailsFilter.Pending, T("Pending Comments").ToString())%>
<%: Html.SelectOption(Model.Options.Filter, CommentDetailsFilter.Spam, T("Spam").ToString())%>
</select>
<input class="button" type="submit" name="submit.Filter" value="<%: T("Apply") %>"/>
</fieldset>
<fieldset>
<table class="items" summary="<%: T("This is a table of the comments for the content item") %>">
<colgroup>
<col id="Col1" />
<col id="Col2" />
<col id="Col3" />
<col id="Col4" />
<col id="Col5" />
<col id="Col6" />
</colgroup>
<thead>
<tr>
<th scope="col">&nbsp;&darr;<%-- todo: (heskew) something more appropriate for "this applies to the bulk actions --%></th>
<th scope="col"><%: T("Status") %></th>
<th scope="col"><%: T("Author") %></th>
<th scope="col"><%: T("Comment") %></th>
<th scope="col"><%: T("Date") %></th>
<th scope="col"></th>
</tr>
</thead>
<%
int commentIndex = 0;
foreach (var commentEntry in Model.Comments) {
var ci = commentIndex;
%>
<tr>
<td>
<input type="hidden" value="<%=Model.Comments[commentIndex].Comment.Id %>" name="<%: Html.NameOf(m => m.Comments[ci].Comment.Id) %>"/>
<input type="checkbox" value="true" name="<%: Html.NameOf(m => m.Comments[ci].IsChecked) %>"/>
<input type="hidden" value="<%=Model.DisplayNameForCommentedItem %>" name="DisplayNameForCommentedtem" />
<input type="hidden" value="<%=Model.CommentedItemId %>" name="CommentedItemId" />
</td>
<td>
<% if (commentEntry.Comment.Status == CommentStatus.Spam) { %><%: T("Spam") %><% }
else if (commentEntry.Comment.Status == CommentStatus.Pending) { %><%: T("Pending") %><% }
else { %><%: T("Approved") %><% } %>
</td>
<td><%: commentEntry.Comment.UserName %></td>
<td>
<% if (commentEntry.Comment.CommentText != null) {%>
<%: commentEntry.Comment.CommentText.Length > 23 ? commentEntry.Comment.CommentText.Substring(0, 24) : commentEntry.Comment.CommentText %><%: T(" ...") %>
<% } %>
</td>
<td><%: Html.DateTime(commentEntry.Comment.CommentDateUtc.GetValueOrDefault()) %></td>
<td>
<ul class="actions">
<li class="construct">
<a href="<%: Url.Action("Edit", new {commentEntry.Comment.Id}) %>" title="<%: T("Edit Comment")%>"><%: T("Edit")%></a>
</li>
<li class="destruct">
<%-- a form in a form doesn't quite work <% using (Html.BeginFormAntiForgeryPost(Url.Action("Delete", new {id = commentEntry.Comment.Id, redirectToAction = "Details"}), FormMethod.Post, new { @class = "inline" })) { %>
<fieldset>
<button type="submit" class="ibutton remove" title="<%: T("Remove Comment") %>"><%: T("Remove Comment") %></button>
</fieldset><%
} %>
--%> </li>
</ul>
</td>
</tr>
<%
commentIndex++;
} %>
</table>
</fieldset>
<% } %>
<div class="manage"><%
if (Model.CommentsClosedOnItem) {
using (Html.BeginFormAntiForgeryPost(Url.Action("Enable", new { commentedItemId = Model.CommentedItemId }), FormMethod.Post, new { @class = "inline" })) { %>
<fieldset>
<button type="submit" title="<%: T("Enable Comments") %>"><%: T("Enable Comments")%></button>
</fieldset><%
}
} else {
using (Html.BeginFormAntiForgeryPost(Url.Action("Close", new { commentedItemId = Model.CommentedItemId }), FormMethod.Post, new { @class = "inline" })) { %>
<fieldset>
<button type="submit" class="button primaryAction" title="<%: T("Close Comments") %>"><%: T("Close Comments")%></button>
</fieldset><%
}
} %>
</div>

View File

@ -0,0 +1,113 @@
@model Orchard.Comments.ViewModels.CommentsDetailsViewModel
@using Orchard.Comments.Models
<h1>@Html.TitleForPage(T("Comments for {0}", Model.DisplayNameForCommentedItem).ToString())</h1>
<div class="manage">
@if (Model.CommentsClosedOnItem) {
@using (Html.BeginFormAntiForgeryPost(Url.Action("Enable", new { commentedItemId = Model.CommentedItemId }), FormMethod.Post, new { @class = "inline" })) {
<fieldset>
<button type="submit" title="@T("Enable Comments")">@T("Enable Comments")</button>
</fieldset>
}
} else {
@using (Html.BeginFormAntiForgeryPost(Url.Action("Close", new { commentedItemId = Model.CommentedItemId }), FormMethod.Post, new { @class = "inline" })) {
<fieldset>
<button type="submit" class="button primaryAction" title="@T("Close Comments")">@T("Close Comments")</button>
</fieldset>
}
}
</div>
@using(Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary()
<fieldset class="bulk-actions">
<label for="publishActions">@T("Actions:")</label>
<select id="publishActions" name="@Html.NameOf(m => m.Options.BulkAction)">
@Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.None, T("Choose action...").ToString())
@Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.Approve, T("Approve").ToString())
@Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.Pend, T("Pend").ToString())
@Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.MarkAsSpam, T("Mark as Spam").ToString())
@Html.SelectOption(Model.Options.BulkAction, CommentDetailsBulkAction.Delete, T("Remove").ToString())
</select>
<input class="button" type="submit" name="submit.BulkEdit" value="@T("Apply")" />
</fieldset>
<fieldset class="bulk-actions">
<label for="filterResults">@T("Filter:")</label>
<select id="filterResults" name="@Html.NameOf(m => m.Options.Filter)">
@Html.SelectOption(Model.Options.Filter, CommentDetailsFilter.All, T("All Comments").ToString())
@Html.SelectOption(Model.Options.Filter, CommentDetailsFilter.Approved, T("Approved Comments").ToString())
@Html.SelectOption(Model.Options.Filter, CommentDetailsFilter.Pending, T("Pending Comments").ToString())
@Html.SelectOption(Model.Options.Filter, CommentDetailsFilter.Spam, T("Spam").ToString())
</select>
<input class="button" type="submit" name="submit.Filter" value="@T("Apply")"/>
</fieldset>
<fieldset>
<table class="items" summary="@T("This is a table of the comments for the content item")">
<colgroup>
<col id="Col1" />
<col id="Col2" />
<col id="Col3" />
<col id="Col4" />
<col id="Col5" />
<col id="Col6" />
</colgroup>
<thead>
<tr>
<th scope="col">&nbsp;&darr;</th>
<th scope="col">@T("Status")</th>
<th scope="col">@T("Author")</th>
<th scope="col">@T("Comment")</th>
<th scope="col">@T("Date")</th>
<th scope="col"></th>
</tr>
</thead>
@{var commentIndex = 0;}
@foreach (var commentEntry in Model.Comments) {
<tr>
<td>
<input type="hidden" value="@Model.Comments[commentIndex].Comment.Id" name="@Html.NameOf(m => m.Comments[commentIndex].Comment.Id)"/>
<input type="checkbox" value="true" name="@Html.NameOf(m => m.Comments[commentIndex].IsChecked)"/>
<input type="hidden" value="@Model.DisplayNameForCommentedItem" name="DisplayNameForCommentedtem" />
<input type="hidden" value="@Model.CommentedItemId" name="CommentedItemId" />
</td>
<td>
@if (commentEntry.Comment.Status == CommentStatus.Spam) { T("Spam") }
else if (commentEntry.Comment.Status == CommentStatus.Pending) { T("Pending") }
else { T("Approved") }
</td>
<td>@commentEntry.Comment.UserName</td>
<td>
@if (commentEntry.Comment.CommentText != null) {
commentEntry.Comment.CommentText.Length > 23 ? commentEntry.Comment.CommentText.Substring(0, 24) : (commentEntry.Comment.CommentText + T(" ..."))
}
</td>
<td>@Html.DateTime(commentEntry.Comment.CommentDateUtc.GetValueOrDefault())</td>
<td>
<ul class="actions">
<li class="construct">
<a href="@Url.Action("Edit", new {commentEntry.Comment.Id})" title="@T("Edit Comment")">@T("Edit")</a>
</li>
<li class="destruct"></li>
</ul>
</td>
</tr>
commentIndex = commentIndex + 1;
}
</table>
</fieldset>
}
<div class="manage">
@if (Model.CommentsClosedOnItem) {
using (Html.BeginFormAntiForgeryPost(Url.Action("Enable", new { commentedItemId = Model.CommentedItemId }), FormMethod.Post, new { @class = "inline" }))
{
<fieldset>
<button type="submit" title="@T("Enable Comments")">@T("Enable Comments")</button>
</fieldset>
}
} else {
using (Html.BeginFormAntiForgeryPost(Url.Action("Close", new { commentedItemId = Model.CommentedItemId }), FormMethod.Post, new { @class = "inline" })) {
<fieldset>
<button type="submit" class="button primaryAction" title="@T("Close Comments")">@T("Close Comments")</button>
</fieldset>
}
}
</div>

View File

@ -1,45 +0,0 @@
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage<CommentsEditViewModel>" %>
<%@ Import Namespace="Orchard.Comments.Models"%>
<%@ Import Namespace="Orchard.Comments.ViewModels"%>
<h1><%: Html.TitleForPage(T("Edit Comment").ToString())%></h1>
<% using(Html.BeginFormAntiForgeryPost()) { %>
<%: Html.ValidationSummary() %>
<fieldset class="who">
<div>
<label for="Name"><%: T("Name") %></label>
<input id="Name" class="text" name="Name" type="text" value="<%: Model.Name %>" />
</div>
<div>
<label for="Email"><%: T("Email") %></label>
<input id="Email" class="text" name="Email" type="text" value="<%: Model.Email %>" />
</div>
<div>
<label for="SiteName"><%: T("Url") %></label>
<input id="SiteName" class="text" name="SiteName" type="text" value="<%: Model.SiteName %>" />
</div>
</fieldset>
<fieldset class="what">
<div>
<label for="CommentText"><%: T("Body") %></label>
<textarea id="CommentText" rows="10" cols="30" name="CommentText"><%: Model.CommentText %></textarea>
<input id="CommentId" name="Id" type="hidden" value="<%=Model.Id %>" />
</div>
</fieldset>
<fieldset>
<div>
<%: Html.RadioButton("Status", "Pending", (Model.Status == CommentStatus.Pending), new { id = "Status_Pending" }) %>
<label class="forcheckbox" for="Status_Pending"><%: T("Pending") %></label>
</div>
<div>
<%: Html.RadioButton("Status", "Approved", (Model.Status == CommentStatus.Approved), new { id = "Status_Approved" }) %>
<label class="forcheckbox" for="Status_Approved"><%: T("Approved") %></label>
</div>
<div>
<%: Html.RadioButton("Status", "Spam", (Model.Status == CommentStatus.Spam), new { id = "Status_Spam" }) %>
<label class="forcheckbox" for="Status_Spam"><%: T("Mark as spam") %></label>
</div>
</fieldset>
<fieldset>
<input type="submit" class="button" value="<%: T("Save") %>" />
</fieldset>
<% } %>

View File

@ -0,0 +1,45 @@
@model Orchard.Comments.ViewModels.CommentsEditViewModel
@using Orchard.Comments.Models
<h1>@Html.TitleForPage(T("Edit Comment").ToString())</h1>
@using(Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary()
<fieldset class="who">
<div>
<label for="Name">@T("Name")</label>
<input id="Name" class="text" name="Name" type="text" value="@Model.Name" />
</div>
<div>
<label for="Email">@T("Email")</label>
<input id="Email" class="text" name="Email" type="text" value="@Model.Email" />
</div>
<div>
<label for="SiteName">@T("Url")</label>
<input id="SiteName" class="text" name="SiteName" type="text" value="@Model.SiteName" />
</div>
</fieldset>
<fieldset class="what">
<div>
<label for="CommentText">@T("Body")</label>
<textarea id="CommentText" rows="10" cols="30" name="CommentText">@Model.CommentText</textarea>
<input id="CommentId" name="Id" type="hidden" value="@Model.Id" />
</div>
</fieldset>
<fieldset>
<div>
@Html.RadioButton("Status", "Pending", (Model.Status == CommentStatus.Pending), new { id = "Status_Pending" })
<label class="forcheckbox" for="Status_Pending">@T("Pending")</label>
</div>
<div>
@Html.RadioButton("Status", "Approved", (Model.Status == CommentStatus.Approved), new { id = "Status_Approved" })
<label class="forcheckbox" for="Status_Approved">@T("Approved")</label>
</div>
<div>
@Html.RadioButton("Status", "Spam", (Model.Status == CommentStatus.Spam), new { id = "Status_Spam" })
<label class="forcheckbox" for="Status_Spam">@T("Mark as spam")</label>
</div>
</fieldset>
<fieldset>
<input type="submit" class="button" value="@T("Save")" />
</fieldset>
}

View File

@ -1,92 +0,0 @@
<%@ Page Language="C#" Inherits="Orchard.Mvc.ViewPage<CommentsIndexViewModel>" %>
<%@ Import Namespace="Orchard.Comments.Models"%>
<%@ Import Namespace="Orchard.Comments.ViewModels"%>
<h1><%: Html.TitleForPage(T("Manage Comments").ToString())%></h1>
<% using(Html.BeginFormAntiForgeryPost()) { %>
<%: Html.ValidationSummary() %>
<fieldset class="bulk-actions">
<label for="publishActions"><%: T("Actions:") %></label>
<select id="publishActions" name="<%: Html.NameOf(m => m.Options.BulkAction)%>">
<%: Html.SelectOption(Model.Options.BulkAction, CommentIndexBulkAction.None, T("Choose action...").ToString()) %>
<%: Html.SelectOption(Model.Options.BulkAction, CommentIndexBulkAction.Approve, T("Approve").ToString()) %>
<%: Html.SelectOption(Model.Options.BulkAction, CommentIndexBulkAction.Pend, T("Pend").ToString())%>
<%: Html.SelectOption(Model.Options.BulkAction, CommentIndexBulkAction.MarkAsSpam, T("Mark as Spam").ToString())%>
<%: Html.SelectOption(Model.Options.BulkAction, CommentIndexBulkAction.Delete, T("Remove").ToString())%>
</select>
<input class="button" type="submit" name="submit.BulkEdit" value="<%: T("Apply") %>" />
</fieldset>
<fieldset class="bulk-actions">
<label for="filterResults"><%: T("Filter:")%></label>
<select id="filterResults" name="<%: Html.NameOf(m => m.Options.Filter)%>">
<%: Html.SelectOption(Model.Options.Filter, CommentIndexFilter.All, T("All Comments").ToString())%>
<%: Html.SelectOption(Model.Options.Filter, CommentIndexFilter.Approved, T("Approved Comments").ToString())%>
<%: Html.SelectOption(Model.Options.Filter, CommentIndexFilter.Pending, T("Pending Comments").ToString())%>
<%: Html.SelectOption(Model.Options.Filter, CommentIndexFilter.Spam, T("Spam").ToString())%>
</select>
<input class="button" type="submit" name="submit.Filter" value="<%: T("Apply") %>"/>
</fieldset>
<fieldset>
<table class="items" summary="<%: T("This is a table of the comments in your application") %>">
<colgroup>
<col id="Col1" />
<col id="Col2" />
<col id="Col3" />
<col id="Col4" />
<col id="Col5" />
<col id="Col6" />
<col id="Col7" />
</colgroup>
<thead>
<tr>
<th scope="col">&nbsp;&darr;<%-- todo: (heskew) something more appropriate for "this applies to the bulk actions --%></th>
<th scope="col"><%: T("Status") %></th>
<th scope="col"><%: T("Author") %></th>
<th scope="col"><%: T("Comment") %></th>
<th scope="col"><%: T("Date") %></th>
<th scope="col"><%: T("Commented On") %></th>
<th scope="col"></th>
</tr>
</thead>
<%
int commentIndex = 0;
foreach (var commentEntry in Model.Comments) {
var ci = commentIndex;
%>
<tr>
<td>
<input type="hidden" value="<%=Model.Comments[commentIndex].Comment.Id %>" name="<%: Html.NameOf(m => m.Comments[ci].Comment.Id) %>"/>
<input type="checkbox" value="true" name="<%: Html.NameOf(m => m.Comments[ci].IsChecked) %>"/>
</td>
<td><% if (commentEntry.Comment.Status == CommentStatus.Spam) { %><%: T("Spam") %><% }
else if (commentEntry.Comment.Status == CommentStatus.Pending) { %><%: T("Pending") %><% }
else { %><%: T("Approved") %><% } %></td>
<td><%: commentEntry.Comment.UserName %></td>
<td>
<% if (commentEntry.Comment.CommentText != null) {%>
<%-- todo: (heskew) same text processing comment as on the public display, also need to use the ellipsis character instead of ... --%>
<%: commentEntry.Comment.CommentText.Length > 23 ? commentEntry.Comment.CommentText.Substring(0, 24) : commentEntry.Comment.CommentText %><%: T(" ...") %>
<% } %>
</td>
<td><%: Html.DateTime(commentEntry.Comment.CommentDateUtc.GetValueOrDefault()) %></td>
<td><%: Html.ActionLink(commentEntry.CommentedOn, "Details", new { id = commentEntry.Comment.CommentedOn }) %></td>
<td>
<ul class="actions">
<li class="construct">
<a href="<%: Url.Action("Edit", new {commentEntry.Comment.Id}) %>" title="<%: T("Edit")%>"><%: T("Edit")%></a>
</li>
<li class="destruct">
<%-- a form in a form doesn't quite work <% using (Html.BeginFormAntiForgeryPost(Url.Action("Delete", new {id = commentEntry.Comment.Id, redirectToAction = "Details"}), FormMethod.Post, new { @class = "inline" })) { %>
<fieldset>
<button type="submit" class="ibutton remove" title="<%: T("Remove Comment") %>"><%: T("Remove Comment") %></button>
</fieldset><%
} %>
--%> </li>
</ul>
</td>
</tr>
<%
commentIndex++;
} %>
</table>
</fieldset>
<% } %>

View File

@ -0,0 +1,82 @@
@model Orchard.Comments.ViewModels.CommentsIndexViewModel
@using Orchard.Comments.Models
<h1>@Html.TitleForPage(T("Manage Comments").ToString())</h1>
@using(Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary()
<fieldset class="bulk-actions">
<label for="publishActions">@T("Actions:")</label>
<select id="publishActions" name="@Html.NameOf(m => m.Options.BulkAction)">
@Html.SelectOption(Model.Options.BulkAction, CommentIndexBulkAction.None, T("Choose action...").ToString())
@Html.SelectOption(Model.Options.BulkAction, CommentIndexBulkAction.Approve, T("Approve").ToString())
@Html.SelectOption(Model.Options.BulkAction, CommentIndexBulkAction.Pend, T("Pend").ToString())
@Html.SelectOption(Model.Options.BulkAction, CommentIndexBulkAction.MarkAsSpam, T("Mark as Spam").ToString())
@Html.SelectOption(Model.Options.BulkAction, CommentIndexBulkAction.Delete, T("Remove").ToString())
</select>
<input class="button" type="submit" name="submit.BulkEdit" value="@T("Apply")" />
</fieldset>
<fieldset class="bulk-actions">
<label for="filterResults">@T("Filter:")</label>
<select id="filterResults" name="@Html.NameOf(m => m.Options.Filter)">
@Html.SelectOption(Model.Options.Filter, CommentIndexFilter.All, T("All Comments").ToString())
@Html.SelectOption(Model.Options.Filter, CommentIndexFilter.Approved, T("Approved Comments").ToString())
@Html.SelectOption(Model.Options.Filter, CommentIndexFilter.Pending, T("Pending Comments").ToString())
@Html.SelectOption(Model.Options.Filter, CommentIndexFilter.Spam, T("Spam").ToString())
</select>
<input class="button" type="submit" name="submit.Filter" value="@T("Apply")"/>
</fieldset>
<fieldset>
<table class="items" summary="@T("This is a table of the comments in your application")">
<colgroup>
<col id="Col1" />
<col id="Col2" />
<col id="Col3" />
<col id="Col4" />
<col id="Col5" />
<col id="Col6" />
<col id="Col7" />
</colgroup>
<thead>
<tr>
<th scope="col">&nbsp;&darr;</th>
<th scope="col">@T("Status")</th>
<th scope="col">@T("Author")</th>
<th scope="col">@T("Comment")</th>
<th scope="col">@T("Date")</th>
<th scope="col">@T("Commented On")</th>
<th scope="col"></th>
</tr>
</thead>
@{var commentIndex = 0;}
@foreach (var commentEntry in Model.Comments) {
<tr>
<td>
<input type="hidden" value="@Model.Comments[commentIndex].Comment.Id" name="@Html.NameOf(m => m.Comments[commentIndex].Comment.Id)"/>
<input type="checkbox" value="true" name="@Html.NameOf(m => m.Comments[commentIndex].IsChecked)"/>
</td>
<td>
@if (commentEntry.Comment.Status == CommentStatus.Spam) { T("Spam") }
else if (commentEntry.Comment.Status == CommentStatus.Pending) { T("Pending") }
else { T("Approved") }</td>
<td>@commentEntry.Comment.UserName</td>
<td>
@if (commentEntry.Comment.CommentText != null) {
commentEntry.Comment.CommentText.Length > 23 ? commentEntry.Comment.CommentText.Substring(0, 24) : (commentEntry.Comment.CommentText + T(" ..."))
}
</td>
<td>@Html.DateTime(commentEntry.Comment.CommentDateUtc.GetValueOrDefault())</td>
<td>@Html.ActionLink(commentEntry.CommentedOn, "Details", new { id = commentEntry.Comment.CommentedOn })</td>
<td>
<ul class="actions">
<li class="construct">
<a href="@Url.Action("Edit", new {commentEntry.Comment.Id})" title="@T("Edit")">@T("Edit")</a>
</li>
<li class="destruct"></li>
</ul>
</td>
</tr>
commentIndex = commentIndex + 1;
}
</table>
</fieldset>
}

View File

@ -1,60 +0,0 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<CommentsPart>" %>
<%@ Import Namespace="Orchard.Comments"%>
<%@ Import Namespace="Orchard.Security" %>
<%@ Import Namespace="Orchard.Comments.Models" %>
<%@ Import Namespace="Orchard.Utility.Extensions" %>
<%-- todo: clean up this template - waaay too much going on in here :/ --%><%
if (Model.Comments.Count > 0) { %>
<h2 id="comments"><%: T.Plural("1 Comment", "{0} Comments", Model.Comments.Count)%></h2>
<% Html.RenderPartial("ListOfComments", Model.Comments);
}
if (Model.CommentsActive == false) {
if (Model.Comments.Count > 0) { %>
<p><%: T("Comments have been disabled for this content.") %></p><%
}
}
else if(!Request.IsAuthenticated && !AuthorizedFor(Permissions.AddComment)) { %>
<h2 id="addacomment"><%: T("Add a Comment") %></h2>
<p class="info message"><%: T("You must {0} to comment.", Html.ActionLink(T("log on").ToString(), "LogOn", new { Controller = "Account", Area = "Orchard.Users", ReturnUrl = string.Format("{0}#addacomment", Context.Request.RawUrl) }))%></p><%
}
else { %>
<% using (Html.BeginForm("Create", "Comment", new { area = "Orchard.Comments" }, FormMethod.Post, new { @class = "comment" })) { %>
<%: Html.ValidationSummary() %>
<h2 id="addacomment"><%: T("Add a Comment") %></h2><%
if (!Request.IsAuthenticated) { %>
<fieldset class="who">
<div>
<label for="Name"><%: T("Name") %></label>
<input id="Name" class="text" name="Name" type="text" />
</div>
<div>
<label for="Email"><%: T("Email") %></label>
<input id="Email" class="text" name="Email" type="text" />
</div>
<div>
<label for="SiteName"><%: T("Url") %></label>
<input id="SiteName" class="text" name="SiteName" type="text" />
</div>
</fieldset><%
}
else {
var currentUser = Html.Resolve<IAuthenticationService>().GetAuthenticatedUser();
%>
<%: Html.Hidden("Name", currentUser.UserName ?? "")%>
<%: Html.Hidden("Email", currentUser.Email ?? "")%><%
}%>
<fieldset class="what">
<div>
<label for="CommentText"><% if (Request.IsAuthenticated) { %><%: T("Hi, {0}!", Html.Encode(Page.User.Identity.Name)) %><br /><% } %><%: T("Comment") %></label>
<textarea id="CommentText" rows="10" cols="30" name="CommentText"></textarea>
</div>
<div>
<input type="submit" class="button" value="<%: T("Submit Comment") %>" />
<%: Html.Hidden("CommentedOn", Model.ContentItem.Id) %>
<%: Html.Hidden("ReturnUrl", Context.Request.ToUrlString()) %>
<%: Html.AntiForgeryTokenOrchard() %>
</div>
</fieldset><%
}
} %>

View File

@ -0,0 +1,57 @@
@model Orchard.Comments.Models.CommentsPart
@using Orchard.Comments.Models
@using Orchard.Comments
@using Orchard.Security
@using Orchard.Utility.Extensions
@if (Model.Comments.Count > 0) {
<h2 id="comments">@T.Plural("1 Comment", "{0} Comments", Model.Comments.Count)</h2>
@Html.RenderPartial("ListOfComments", Model.Comments);
}
@if (Model.CommentsActive == false) {
if (Model.Comments.Count > 0) {
<p>@T("Comments have been disabled for this content.")</p>
}
}
else if(!Request.IsAuthenticated && !AuthorizedFor(Permissions.AddComment)) {
<h2 id="addacomment">@T("Add a Comment")</h2>
<p class="info message">@T("You must {0} to comment.", Html.ActionLink(T("log on").ToString(), "LogOn", new { Controller = "Account", Area = "Orchard.Users", ReturnUrl = string.Format("{0}#addacomment", Context.Request.RawUrl) }))</p>
} else {
using (Html.BeginForm("Create", "Comment", new { area = "Orchard.Comments" }, FormMethod.Post, new { @class = "comment" })) {
@Html.ValidationSummary()
<h2 id="addacomment">@T("Add a Comment")</h2>
@if (!Request.IsAuthenticated) {
<fieldset class="who">
<div>
<label for="Name">@T("Name")</label>
<input id="Name" class="text" name="Name" type="text" />
</div>
<div>
<label for="Email">@T("Email")</label>
<input id="Email" class="text" name="Email" type="text" />
</div>
<div>
<label for="SiteName">@T("Url")</label>
<input id="SiteName" class="text" name="SiteName" type="text" />
</div>
</fieldset>
} else {
var currentUser = Html.Resolve<IAuthenticationService>().GetAuthenticatedUser();
@Html.Hidden("Name", currentUser.UserName ?? "")
@Html.Hidden("Email", currentUser.Email ?? "")
}
<fieldset class="what">
<div>
<label for="CommentText">@if (Request.IsAuthenticated) { T("Hi, {0}!", Html.Encode(Page.User.Identity.Name))<br /> } @T("Comment")</label>
<textarea id="CommentText" rows="10" cols="30" name="CommentText"></textarea>
</div>
<div>
<input type="submit" class="button" value="@T("Submit Comment")" />
@Html.Hidden("CommentedOn", Model.ContentItem.Id)
@Html.Hidden("ReturnUrl", Context.Request.ToUrlString())
@Html.AntiForgeryTokenOrchard()
</div>
</fieldset>
}
}

View File

@ -1,3 +0,0 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<CommentCountViewModel>" %>
<%@ Import Namespace="Orchard.Comments.ViewModels"%>
<span class="commentcount"><%: T.Plural("1 Comment", "{0} Comments", Model.CommentCount)%></span>

View File

@ -0,0 +1,4 @@
@model Orchard.Comments.ViewModels.CommentCountViewModel
@using Orchard.Comments.ViewModels
<span class="commentcount">@T.Plural("1 Comment", "{0} Comments", Model.CommentCount)</span>

View File

@ -1,4 +0,0 @@
<%@ 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>

View File

@ -0,0 +1,5 @@
@model Orchard.Comments.ViewModels.CommentCountViewModel
@using Orchard.Comments.ViewModels
@using Orchard.Comments.Extensions
<span class="commentcount">@Html.CommentSummaryLinks(T, Model.Item, Model.CommentCount, Model.PendingCount)</span>

View File

@ -1,17 +0,0 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<CommentsPart>" %>
<%@ 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><%: T("Comments")%><% if (Model.Comments.Count > 0) { %> <span>&#150; <%: Html.CommentSummaryLinks(T, Model.ContentItem, Model.Comments.Count, Model.PendingComments.Count)%></span><% } %></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>
</fieldset>

View File

@ -0,0 +1,16 @@
@model Orchard.Comments.Models.CommentsPart
@using Orchard.Comments.Models
@using Orchard.Comments.Extensions
@using Orchard.Localization
<fieldset>
<legend>@T("Comments")
@if (Model.Comments.Count > 0) {
<span>&#150; @Html.CommentSummaryLinks(T, Model.ContentItem, Model.Comments.Count, Model.PendingComments.Count)</span>
}
</legend>
@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>
</fieldset>

View File

@ -1,25 +0,0 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<CommentSettingsPartRecord>" %>
<%@ Import Namespace="Orchard.Comments.Models"%>
<fieldset>
<legend><%: T("Comments")%></legend>
<div>
<%: Html.EditorFor(m => m.ModerateComments) %>
<label class="forcheckbox" for="CommentSettings_ModerateComments"><%: T("Comments must be approved before they appear")%></label>
<%: Html.ValidationMessage("ModerateComments", "*")%>
</div>
<div>
<%: Html.EditorFor(m => m.EnableSpamProtection) %>
<label class="forcheckbox" for="<%:Html.FieldIdFor(m => m.EnableSpamProtection) %>"><%: T("Enable spam protection") %></label>
<%: Html.ValidationMessage("EnableSpamProtection", "*")%>
</div>
<div data-controllerid="<%:Html.FieldIdFor(m => m.EnableSpamProtection) %>">
<label for="CommentSettings_AkismetKey"><%: T("Akismet key") %></label>
<%: Html.EditorFor(m => m.AkismetKey) %>
<%: Html.ValidationMessage("AkismetKey", "*")%>
</div>
<div data-controllerid="<%:Html.FieldIdFor(m => m.EnableSpamProtection) %>">
<label for="CommentSettings_AkismetUrl"><%: T("Blog URL")%></label>
<%: Html.EditorFor(m => m.AkismetUrl) %>
<%: Html.ValidationMessage("AkismetUrl", "*")%>
</div>
</fieldset>

View File

@ -0,0 +1,26 @@
@model Orchard.Comments.Models.CommentSettingsPartRecord
@using Orchard.Comments.Models
<fieldset>
<legend>@T("Comments")</legend>
<div>
@Html.EditorFor(m => m.ModerateComments)
<label class="forcheckbox" for="CommentSettings_ModerateComments">@T("Comments must be approved before they appear")</label>
@Html.ValidationMessage("ModerateComments", "*")
</div>
<div>
@Html.EditorFor(m => m.EnableSpamProtection)
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.EnableSpamProtection)">@T("Enable spam protection")</label>
@Html.ValidationMessage("EnableSpamProtection", "*")
</div>
<div data-controllerid="@Html.FieldIdFor(m => m.EnableSpamProtection)">
<label for="CommentSettings_AkismetKey">@T("Akismet key")</label>
@Html.EditorFor(m => m.AkismetKey)
@Html.ValidationMessage("AkismetKey", "*")
</div>
<div data-controllerid="@Html.FieldIdFor(m => m.EnableSpamProtection)">
<label for="CommentSettings_AkismetUrl">@T("Blog URL")</label>
@Html.EditorFor(m => m.AkismetUrl)
@Html.ValidationMessage("AkismetUrl", "*")
</div>
</fieldset>

View File

@ -1,17 +0,0 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<IEnumerable<CommentPart>>" %>
<%@ Import Namespace="Orchard.Comments.Models"%>
<ul class="comments"><%
foreach (var comment in Model) { %>
<li>
<div class="comment">
<span class="who"><%: Html.LinkOrDefault(comment.Record.UserName, comment.Record.SiteName, new { rel = "nofollow" })%></span>
<%-- todo: (heskew) need comment permalink --%>
<span>said <%: Html.Link(Html.DateTimeRelative(comment.Record.CommentDateUtc.GetValueOrDefault(), T).ToString(), "#")%></span>
</div>
<div class="text">
<%-- todo: (heskew) comment text needs processing depending on comment markup style --%>
<p><%: comment.Record.CommentText %></p>
</div>
</li><%
} %>
</ul>

View File

@ -0,0 +1,16 @@
@model IEnumerable<Orchard.Comments.Models.CommentPart>
@using Orchard.Comments.Models
<ul class="comments">
@foreach (var comment in Model) {
<li>
<div class="comment">
<span class="who">@Html.LinkOrDefault(comment.Record.UserName, comment.Record.SiteName, new { rel = "nofollow" })</span>
<span>said @Html.Link(Html.DateTimeRelative(comment.Record.CommentDateUtc.GetValueOrDefault(), T).ToString(), "#")</span>
</div>
<div class="text">
<p>@comment.Record.CommentText</p>
</div>
</li>
}
</ul>

View File

@ -87,7 +87,7 @@ namespace Orchard.Setup.Services {
"Orchard.Modules",
"Orchard.Themes",
//"Orchard.Blogs",
//"Orchard.Comments",
"Orchard.Comments",
"Orchard.Tags",
"Orchard.Media",
//"Futures.Widgets"

View File

@ -68,6 +68,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Media", "Orchard.We
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Email", "Orchard.Web\Modules\Orchard.Email\Orchard.Email.csproj", "{05660F47-D649-48BD-9DED-DF4E01E7CFF9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Comments", "Orchard.Web\Modules\Orchard.Comments\Orchard.Comments.csproj", "{14C049FD-B35B-415A-A824-87F26B26E7FD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
CodeCoverage|Any CPU = CodeCoverage|Any CPU
@ -347,6 +349,16 @@ Global
{05660F47-D649-48BD-9DED-DF4E01E7CFF9}.FxCop|Any CPU.Build.0 = Release|Any CPU
{05660F47-D649-48BD-9DED-DF4E01E7CFF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{05660F47-D649-48BD-9DED-DF4E01E7CFF9}.Release|Any CPU.Build.0 = Release|Any CPU
{14C049FD-B35B-415A-A824-87F26B26E7FD}.CodeCoverage|Any CPU.ActiveCfg = Release|Any CPU
{14C049FD-B35B-415A-A824-87F26B26E7FD}.CodeCoverage|Any CPU.Build.0 = Release|Any CPU
{14C049FD-B35B-415A-A824-87F26B26E7FD}.Coverage|Any CPU.ActiveCfg = Release|Any CPU
{14C049FD-B35B-415A-A824-87F26B26E7FD}.Coverage|Any CPU.Build.0 = Release|Any CPU
{14C049FD-B35B-415A-A824-87F26B26E7FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{14C049FD-B35B-415A-A824-87F26B26E7FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{14C049FD-B35B-415A-A824-87F26B26E7FD}.FxCop|Any CPU.ActiveCfg = Release|Any CPU
{14C049FD-B35B-415A-A824-87F26B26E7FD}.FxCop|Any CPU.Build.0 = Release|Any CPU
{14C049FD-B35B-415A-A824-87F26B26E7FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{14C049FD-B35B-415A-A824-87F26B26E7FD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -365,6 +377,7 @@ Global
{72457126-E118-4171-A08F-9A709EE4B7FC} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
{D9A7B330-CD22-4DA1-A95A-8DE1982AD8EB} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
{05660F47-D649-48BD-9DED-DF4E01E7CFF9} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
{14C049FD-B35B-415A-A824-87F26B26E7FD} = {E9C9F120-07BA-4DFB-B9C3-3AFB9D44C9D5}
{ABC826D4-2FA1-4F2F-87DE-E6095F653810} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA}
{F112851D-B023-4746-B6B1-8D2E5AD8F7AA} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA}
{6CB3EB30-F725-45C0-9742-42599BA8E8D2} = {74E681ED-FECC-4034-B9BD-01B0BB1BDECA}