Adding support for html filters on comments

--HG--
branch : 1.x
extra : rebase_source : cb25657e65a761bab674e4f175ad38327c46a278
This commit is contained in:
Sebastien Ros
2012-11-02 16:12:59 -07:00
parent 2cd444ceb7
commit 171a163a8a
16 changed files with 126 additions and 41 deletions

View File

@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml;
using JetBrains.Annotations;
using Orchard.Comments.Models;
using Orchard.Comments.Settings;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.Aspects;
@@ -17,6 +20,7 @@ namespace Orchard.Comments.Drivers {
private readonly IWorkContextAccessor _workContextAccessor;
private readonly IClock _clock;
private readonly ICommentValidator _commentValidator;
private readonly IEnumerable<IHtmlFilter> _htmlFilters;
protected override string Prefix { get { return "Comments"; } }
@@ -27,19 +31,28 @@ namespace Orchard.Comments.Drivers {
IWorkContextAccessor workContextAccessor,
IClock clock,
ICommentService commentService,
ICommentValidator commentValidator) {
ICommentValidator commentValidator,
IEnumerable<IHtmlFilter> htmlFilters) {
_contentManager = contentManager;
_workContextAccessor = workContextAccessor;
_clock = clock;
_commentValidator = commentValidator;
_htmlFilters = htmlFilters;
T = NullLocalizer.Instance;
}
protected override DriverResult Display(CommentPart part, string displayType, dynamic shapeHelper) {
var formattedText = new Lazy<string>(() => {
var commentsPart = _contentManager.Get<CommentsPart>(part.CommentedOn);
var settings = commentsPart.TypePartDefinition.Settings.GetModel<CommentsPartSettings>();
var formatted = _htmlFilters.Where(x => x.GetType().Name.Equals(settings.HtmlFilter, StringComparison.OrdinalIgnoreCase)).Aggregate(part.CommentText, (text, filter) => filter.ProcessContent(text));
return formatted;
});
return Combined(
ContentShape("Parts_Comment", () => shapeHelper.Parts_Comment()),
ContentShape("Parts_Comment_SummaryAdmin", () => shapeHelper.Parts_Comment_SummaryAdmin())
ContentShape("Parts_Comment", () => shapeHelper.Parts_Comment(FormattedText: formattedText.Value)),
ContentShape("Parts_Comment_SummaryAdmin", () => shapeHelper.Parts_Comment_SummaryAdmin(FormattedText: formattedText.Value))
);
}

View File

@@ -74,6 +74,7 @@
<Compile Include="Rules\CommentsActions.cs" />
<Compile Include="Rules\CommentsForms.cs" />
<Compile Include="Services\CommentValidator.cs" />
<Compile Include="Services\HtmlEncodeFilter.cs" />
<Compile Include="Services\ICheckSpamEventHandler.cs" />
<Compile Include="Settings\CommentsPartSettings.cs" />
<Compile Include="Settings\CommentsPartSettingsEvents.cs" />
@@ -102,6 +103,7 @@
<Compile Include="Services\ICommentValidator.cs" />
<Compile Include="ViewModels\CommentsDetailsViewModel.cs" />
<Compile Include="ViewModels\CommentsIndexViewModel.cs" />
<Compile Include="ViewModels\CommentsPartSettingsViewModel.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Module.txt" />
@@ -162,7 +164,7 @@
<Content Include="Views\Content-Comment.SummaryAdmin.cshtml" />
<Content Include="Views\ListOfComments.cshtml" />
<Content Include="Views\CommentReplyButton.cshtml" />
<Content Include="Views\DefinitionTemplates\CommentsPartSettings.cshtml" />
<Content Include="Views\DefinitionTemplates\CommentsPartSettingsViewModel.cshtml" />
<None Include="Views\Parts.Comment.SummaryAdmin.cshtml" />
</ItemGroup>
<PropertyGroup>

View File

@@ -0,0 +1,12 @@
using System;
using System.Web;
using Orchard.Services;
namespace Orchard.Comments.Services {
public class HtmlEncodeFilter : IHtmlFilter {
public string ProcessContent(string text) {
return HttpUtility.HtmlEncode(Convert.ToString(text)).Replace("\r\n", "<br />\r\n");
}
}
}

View File

@@ -1,6 +1,13 @@
namespace Orchard.Comments.Settings {
using Orchard.Comments.Services;
namespace Orchard.Comments.Settings {
public class CommentsPartSettings {
public CommentsPartSettings() {
HtmlFilter = typeof (HtmlEncodeFilter).Name;
}
public bool DefaultThreadedComments { get; set; }
public bool MustBeAuthenticated { get; set; }
public string HtmlFilter { get; set; }
}
}

View File

@@ -1,14 +1,21 @@
using System.Collections.Generic;
using System.Globalization;
using Orchard.Comments.ViewModels;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Builders;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.ContentManagement.ViewModels;
using Orchard.Localization;
using Orchard.Services;
namespace Orchard.Comments.Settings {
public class CommentsPartSettingsEvents : ContentDefinitionEditorEventsBase {
private readonly IEnumerable<IHtmlFilter> _htmlFilters;
public CommentsPartSettingsEvents(IEnumerable<IHtmlFilter> htmlFilters) {
_htmlFilters = htmlFilters;
}
public Localizer T { get; set; }
@@ -16,24 +23,29 @@ namespace Orchard.Comments.Settings {
if (definition.PartDefinition.Name != "CommentsPart")
yield break;
var settings = definition.Settings.GetModel<CommentsPartSettings>();
var model = new CommentsPartSettingsViewModel {
Settings = definition.Settings.GetModel<CommentsPartSettings>(),
HtmlFilters = _htmlFilters
};
yield return DefinitionTemplate(settings);
yield return DefinitionTemplate(model);
}
public override IEnumerable<TemplateViewModel> TypePartEditorUpdate(ContentTypePartDefinitionBuilder builder, IUpdateModel updateModel) {
if (builder.Name != "CommentsPart")
yield break;
var settings = new CommentsPartSettings {
var model = new CommentsPartSettingsViewModel {
Settings = new CommentsPartSettings()
};
if (updateModel.TryUpdateModel(settings, "CommentsPartSettings", null, null)) {
builder.WithSetting("CommentsPartSettings.DefaultThreadedComments", settings.DefaultThreadedComments.ToString(CultureInfo.InvariantCulture));
builder.WithSetting("CommentsPartSettings.MustBeAuthenticated", settings.MustBeAuthenticated.ToString(CultureInfo.InvariantCulture));
if (updateModel.TryUpdateModel(model, "CommentsPartSettingsViewModel", null, null)) {
builder.WithSetting("CommentsPartSettings.DefaultThreadedComments", model.Settings.DefaultThreadedComments.ToString(CultureInfo.InvariantCulture));
builder.WithSetting("CommentsPartSettings.MustBeAuthenticated", model.Settings.MustBeAuthenticated.ToString(CultureInfo.InvariantCulture));
builder.WithSetting("CommentsPartSettings.HtmlFilter", model.Settings.HtmlFilter);
}
yield return DefinitionTemplate(settings);
yield return DefinitionTemplate(model);
}
}
}

View File

@@ -0,0 +1,15 @@
using System.Collections.Generic;
using System.Linq;
using Orchard.Comments.Settings;
using Orchard.Services;
namespace Orchard.Comments.ViewModels {
public class CommentsPartSettingsViewModel {
public CommentsPartSettingsViewModel() {
HtmlFilters = Enumerable.Empty<IHtmlFilter>();
}
public CommentsPartSettings Settings { get; set; }
public IEnumerable<IHtmlFilter> HtmlFilters { get; set; }
}
}

View File

@@ -1,13 +0,0 @@
@model Orchard.Comments.Settings.CommentsPartSettings
<fieldset>
<div>
@Html.EditorFor(m => m.DefaultThreadedComments)
<label class="forcheckbox" for="@Html.FieldIdFor( m => m.DefaultThreadedComments)">@T("Use threaded comments by default")</label>
</div>
<div>
@Html.EditorFor(m => m.MustBeAuthenticated)
<label class="forcheckbox" for="@Html.FieldIdFor( m => m.MustBeAuthenticated)">@T("Users must be authenticated to comment")</label>
</div>
</fieldset>

View File

@@ -0,0 +1,32 @@
@using Orchard.Utility.Extensions
@model Orchard.Comments.ViewModels.CommentsPartSettingsViewModel
<fieldset>
<div>
<label for="@Html.FieldIdFor(m => m.Settings.HtmlFilter)" class="forcheckbox">@T("Comments formatting")</label>
<select id="@Html.FieldIdFor(m => m.Settings.HtmlFilter)" name="@Html.FieldNameFor(m => m.Settings.HtmlFilter)">
@Html.SelectOption("", String.IsNullOrWhiteSpace(Model.Settings.HtmlFilter), T("No formatting").ToString())
@foreach(var htmlFilter in Model.HtmlFilters) {
var htmlFilterName = htmlFilter.GetType().Name;
@Html.SelectOption(htmlFilterName, htmlFilterName.Equals(Model.Settings.HtmlFilter, StringComparison.OrdinalIgnoreCase), htmlFilterName.CamelFriendly())
}
</select>
@Html.ValidationMessageFor(m => m.Settings.HtmlFilter)
</div>
</fieldset>
<fieldset>
<div>
@Html.EditorFor(m => m.Settings.DefaultThreadedComments)
<label class="forcheckbox" for="@Html.FieldIdFor( m => m.Settings.DefaultThreadedComments)">@T("Use threaded comments by default")</label>
</div>
</fieldset>
<fieldset>
<div>
@Html.EditorFor(m => m.Settings.MustBeAuthenticated)
<label class="forcheckbox" for="@Html.FieldIdFor( m => m.Settings.MustBeAuthenticated)">@T("Users must be authenticated to comment")</label>
</div>
</fieldset>

View File

@@ -14,5 +14,8 @@
}
</h4>
</header>
<p class="text">@(new MvcHtmlString(Html.Encode(comment.Record.CommentText).Replace("\r\n", "<br />\r\n")))</p>
<p class="text">@Html.Raw(Convert.ToString(Model.FormattedText))</p>
@**@