Skip to content

Commit

Permalink
#6193: IHtmlFilter and TokenFilter improvements and bugfixes (#6938)
Browse files Browse the repository at this point in the history
* IHtmlFilter and TokenFilter improvements and bugfixes.

This changeset unifies the two separate TokenFilter implementations (one for BodyPart, TextField, etc and another one for certain elements such as Html).
It also fixes a bug with the TokenFilter when executing for HtmlWidget, where the wrong content item is being recorded by the handler (the original implementation).
Thirdly, it removes awkward code repetition by moving filter execution into a dedicated HtmlFilterRunner service.

* Renaming IHtmlFilterRunner to IHtmlFilterProcessor (and its references)

* Applying IHtmlFilterProcessor to HtmlMenuItems too + code styling in BodyPartDriver

* Fixing FeedControllerTests.CorePartValuesAreExtracted

* Code styling

---------

Co-authored-by: Jean-Thierry Kéchichian <jean-thierry.kechichian@wanadoo.fr>
Co-authored-by: Sipke Schoorstra <sipke@ideliverable.com>
Co-authored-by: Benedek Farkas <benedek.farkas@lombiq.com>
  • Loading branch information
4 people committed Apr 19, 2024
1 parent 9b0d78b commit cf4335e
Show file tree
Hide file tree
Showing 33 changed files with 200 additions and 236 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using Orchard.Tests.Modules;
using Orchard.Tests.Stubs;
using Orchard.Core.Title.Models;
using Orchard.Services;

namespace Orchard.Core.Tests.Feeds.Controllers {
[TestFixture]
Expand Down Expand Up @@ -177,6 +178,7 @@ class StubItemBuilder : IFeedItemBuilder {
builder.RegisterInstance(mockContentManager.Object).As<IContentManager>();
builder.RegisterType<RssFeedBuilder>().As<IFeedBuilderProvider>();
builder.RegisterType<CorePartsFeedItemBuilder>().As<IFeedItemBuilder>();
builder.RegisterType<HtmlFilterProcessor>().As<IHtmlFilterProcessor>();
builder.RegisterInstance(query).As<IFeedQueryProvider>();
var container = builder.Build();

Expand Down
45 changes: 15 additions & 30 deletions src/Orchard.Web/Core/Common/Drivers/BodyPartDriver.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web;
using Orchard.Mvc.Html;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.ContentManagement.Drivers;
using Orchard.Core.Common.Models;
using Orchard.Core.Common.Settings;
using Orchard.Core.Common.ViewModels;
using Orchard.Services;
using System.Web.Mvc;
Expand All @@ -15,13 +12,13 @@

namespace Orchard.Core.Common.Drivers {
public class BodyPartDriver : ContentPartDriver<BodyPart> {
private readonly IEnumerable<IHtmlFilter> _htmlFilters;
private readonly IHtmlFilterProcessor _htmlFilterProcessor;
private readonly RequestContext _requestContext;

private const string TemplateName = "Parts.Common.Body";

public BodyPartDriver(IOrchardServices services, IEnumerable<IHtmlFilter> htmlFilters, RequestContext requestContext) {
_htmlFilters = htmlFilters;
public BodyPartDriver(IOrchardServices services, IHtmlFilterProcessor htmlFilterProcessor, RequestContext requestContext) {
_htmlFilterProcessor = htmlFilterProcessor;
Services = services;
_requestContext = requestContext;
}
Expand All @@ -33,32 +30,27 @@ public class BodyPartDriver : ContentPartDriver<BodyPart> {
}

protected override DriverResult Display(BodyPart part, string displayType, dynamic shapeHelper) {
string GetProcessedBodyText() => _htmlFilterProcessor.ProcessFilters(part.Text, part.GetFlavor(), part);

return Combined(
ContentShape("Parts_Common_Body",
() => {
var bodyText = _htmlFilters.Aggregate(part.Text, (text, filter) => filter.ProcessContent(text, GetFlavor(part)));
return shapeHelper.Parts_Common_Body(Html: new HtmlString(bodyText));
}),
ContentShape("Parts_Common_Body_Summary",
() => {
var bodyText = _htmlFilters.Aggregate(part.Text, (text, filter) => filter.ProcessContent(text, GetFlavor(part)));
return shapeHelper.Parts_Common_Body_Summary(Html: new HtmlString(bodyText));
})
);
ContentShape("Parts_Common_Body", () =>
shapeHelper.Parts_Common_Body(Html: new HtmlString(GetProcessedBodyText()))),
ContentShape("Parts_Common_Body_Summary", () =>
shapeHelper.Parts_Common_Body_Summary(Html: new HtmlString(GetProcessedBodyText()))));
}

protected override DriverResult Editor(BodyPart part, dynamic shapeHelper) {
var model = BuildEditorViewModel(part,_requestContext);
return ContentShape("Parts_Common_Body_Edit",
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix));
return ContentShape("Parts_Common_Body_Edit", () =>
shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix));
}

protected override DriverResult Editor(BodyPart part, IUpdateModel updater, dynamic shapeHelper) {
var model = BuildEditorViewModel(part, _requestContext);
updater.TryUpdateModel(model, Prefix, null, null);

return ContentShape("Parts_Common_Body_Edit",
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix));
return ContentShape("Parts_Common_Body_Edit", () =>
shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: Prefix));
}

protected override void Importing(BodyPart part, ContentManagement.Handlers.ImportContentContext context) {
Expand All @@ -83,18 +75,11 @@ public class BodyPartDriver : ContentPartDriver<BodyPart> {
private static BodyEditorViewModel BuildEditorViewModel(BodyPart part,RequestContext requestContext) {
return new BodyEditorViewModel {
BodyPart = part,
EditorFlavor = GetFlavor(part),
EditorFlavor = part.GetFlavor(),
AddMediaPath = new PathBuilder(part,requestContext).AddContentType().AddContainerSlug().ToString()
};
}

private static string GetFlavor(BodyPart part) {
var typePartSettings = part.Settings.GetModel<BodyTypePartSettings>();
return (typePartSettings != null && !string.IsNullOrWhiteSpace(typePartSettings.Flavor))
? typePartSettings.Flavor
: part.PartDefinition.Settings.GetModel<BodyPartSettings>().FlavorDefault;
}

class PathBuilder {
private readonly IContent _content;
private string _path;
Expand Down
9 changes: 4 additions & 5 deletions src/Orchard.Web/Core/Common/Drivers/TextFieldDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@

namespace Orchard.Core.Common.Drivers {
public class TextFieldDriver : ContentFieldDriver<TextField> {
private readonly IEnumerable<IHtmlFilter> _htmlFilters;
private readonly IHtmlFilterProcessor _htmlFilterProcessor;

public TextFieldDriver(IOrchardServices services, IEnumerable<IHtmlFilter> htmlFilters) {
_htmlFilters = htmlFilters;
public TextFieldDriver(IOrchardServices services, IHtmlFilterProcessor htmlFilterProcessor) {
_htmlFilterProcessor = htmlFilterProcessor;
Services = services;
T = NullLocalizer.Instance;
}
Expand All @@ -37,8 +37,7 @@ public class TextFieldDriver : ContentFieldDriver<TextField> {
return ContentShape("Fields_Common_Text", GetDifferentiator(field, part),
() => {
var settings = field.PartFieldDefinition.Settings.GetModel<TextFieldSettings>();
object fieldValue = new HtmlString(_htmlFilters.Aggregate(field.Value, (text, filter) => filter.ProcessContent(text, settings.Flavor)));
var fieldValue = new HtmlString(_htmlFilterProcessor.ProcessFilters(field.Value, settings.Flavor, part));
return shapeHelper.Fields_Common_Text(Name: field.Name, Value: fieldValue);
});
}
Expand Down
8 changes: 8 additions & 0 deletions src/Orchard.Web/Core/Common/Models/BodyPart.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Orchard.ContentManagement;
using Orchard.Core.Common.Settings;

namespace Orchard.Core.Common.Models {
public class BodyPart : ContentPart<BodyPartRecord> {
Expand All @@ -11,5 +12,12 @@ public class BodyPart : ContentPart<BodyPartRecord> {
get { return Retrieve(x => x.Format); }
set { Store(x => x.Format, value); }
}

public string GetFlavor() {
var typePartSettings = Settings.GetModel<BodyTypePartSettings>();
return string.IsNullOrWhiteSpace(typePartSettings?.Flavor)
? PartDefinition.Settings.GetModel<BodyPartSettings>().FlavorDefault
: typePartSettings.Flavor;
}
}
}
21 changes: 10 additions & 11 deletions src/Orchard.Web/Core/Common/Services/BbcodeFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,26 @@
using Orchard.Services;

namespace Orchard.Core.Common.Services {
public class BbcodeFilter : IHtmlFilter {
public string ProcessContent(string text, string flavor) {
return BbcodeReplace(text);
public class BbcodeFilter : HtmlFilter {
public override string ProcessContent(string text, HtmlFilterContext context) {
return BbcodeReplace(text, context);
}

// Can be moved somewhere else once we have IoC enabled body text filters.
private static string BbcodeReplace(string text) {
if (string.IsNullOrEmpty(text))
return string.Empty;
private static string BbcodeReplace(string text, HtmlFilterContext context) {
if (String.IsNullOrEmpty(text))
return String.Empty;

// optimize code path if nothing to do
// Optimize code path if nothing to do.
if (!text.Contains("[url]") && !text.Contains("[img]") && !text.Contains("[url=")) {
return text;
}

var sb = new StringBuilder(text);

var index = -1;
var allIndexes = new List<int>();

// process all [url]
// Process all [url].
while (-1 != (index = text.IndexOf("[url]", index + 1, StringComparison.Ordinal))) {
allIndexes.Add(index);
}
Expand Down Expand Up @@ -63,7 +62,7 @@ public class BbcodeFilter : IHtmlFilter {
var url = text.Substring(start + 5, urlEnd - start - 5);
var title = text.Substring(urlEnd + 1, end - urlEnd - 1);

// substitue [url] by <a>
// Substitute [url] by <a>.
sb.Remove(start, end - start + 6);
sb.Insert(start, String.Format("<a href=\"{0}\">{1}</a>", url, title));
}
Expand All @@ -85,7 +84,7 @@ public class BbcodeFilter : IHtmlFilter {

var url = text.Substring(start + 5, end - start - 5);

// substitue [url] by <a>
// Substitue [url] by <a>.
sb.Remove(start, end - start + 6);

if (!string.IsNullOrEmpty(url)) {
Expand Down
6 changes: 3 additions & 3 deletions src/Orchard.Web/Core/Common/Services/TextFieldFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
using Orchard.Utility.Extensions;

namespace Orchard.Core.Common.Services {
public class TextFieldFilter : IHtmlFilter {
public string ProcessContent(string text, string flavor) {
public class TextFieldFilter : HtmlFilter {
public override string ProcessContent(string text, HtmlFilterContext context) {
// Flavor is null for a normal input/text field
return flavor == null || string.Equals(flavor, "textarea", StringComparison.OrdinalIgnoreCase) ? ReplaceNewLines(text) : text;
return context.Flavor == null || String.Equals(context.Flavor, "textarea", StringComparison.OrdinalIgnoreCase) ? ReplaceNewLines(text) : text;
}

private static string ReplaceNewLines(string text) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,24 @@ namespace Orchard.Core.Feeds.StandardBuilders {
public class CorePartsFeedItemBuilder : IFeedItemBuilder {
private readonly IContentManager _contentManager;
private readonly RouteCollection _routes;
private readonly IEnumerable<IHtmlFilter> _htmlFilters;
private readonly IHtmlFilterProcessor _htmlFilterProcessor;

public CorePartsFeedItemBuilder(
IContentManager contentManager,
RouteCollection routes,
IEnumerable<IHtmlFilter> htmlFilters) {
IHtmlFilterProcessor htmlFilterProcessor) {
_contentManager = contentManager;
_routes = routes;
_htmlFilters = htmlFilters;
_htmlFilterProcessor = htmlFilterProcessor;
}

public void Populate(FeedContext context) {
foreach (var feedItem in context.Response.Items.OfType<FeedItem<ContentItem>>()) {

var inspector = new ItemInspector(
feedItem.Item,
_contentManager.GetItemMetadata(feedItem.Item),
_htmlFilters);
_contentManager.GetItemMetadata(feedItem.Item),
_htmlFilterProcessor);

// author is intentionally left empty as it could result in unwanted spam

Expand Down
12 changes: 6 additions & 6 deletions src/Orchard.Web/Core/Feeds/StandardBuilders/ItemInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ namespace Orchard.Core.Feeds.StandardBuilders {
public class ItemInspector {
private readonly IContent _item;
private readonly ContentItemMetadata _metadata;
private readonly IEnumerable<IHtmlFilter> _htmlFilters;
private readonly IHtmlFilterProcessor _htmlFilterProcessor;
private readonly ICommonPart _common;
private readonly ITitleAspect _titleAspect;
private readonly BodyPart _body;

public ItemInspector(IContent item, ContentItemMetadata metadata) : this(item, metadata, Enumerable.Empty<IHtmlFilter>()) {}
public ItemInspector(IContent item, ContentItemMetadata metadata) : this(item, metadata, null) {}

public ItemInspector(IContent item, ContentItemMetadata metadata, IEnumerable<IHtmlFilter> htmlFilters) {
public ItemInspector(IContent item, ContentItemMetadata metadata, IHtmlFilterProcessor htmlFilterProcessor) {
_item = item;
_metadata = metadata;
_htmlFilters = htmlFilters;
_htmlFilterProcessor = htmlFilterProcessor;
_common = item.Get<ICommonPart>();
_titleAspect = item.Get<ITitleAspect>();
_body = item.Get<BodyPart>();
Expand All @@ -49,8 +49,8 @@ public class ItemInspector {

public string Description {
get {
if (_body != null && !string.IsNullOrEmpty(_body.Text)) {
return _htmlFilters.Aggregate(_body.Text, (text, filter) => filter.ProcessContent(text, GetFlavor(_body)));
if (_htmlFilterProcessor != null && _body != null && !string.IsNullOrEmpty(_body.Text)) {
return _htmlFilterProcessor.ProcessFilters(_body.Text, GetFlavor(_body), _body);
}
return Title;
}
Expand Down
13 changes: 6 additions & 7 deletions src/Orchard.Web/Core/Feeds/StandardQueries/ContainerFeedQuery.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Xml.Linq;
using Orchard.ContentManagement;
Expand All @@ -8,16 +7,16 @@
using Orchard.Core.Feeds.StandardBuilders;
using Orchard.Mvc.Extensions;
using Orchard.Services;
using Orchard.Utility.Extensions;

namespace Orchard.Core.Feeds.StandardQueries {
namespace Orchard.Core.Feeds.StandardQueries
{
public class ContainerFeedQuery : IFeedQueryProvider, IFeedQuery {
private readonly IContentManager _contentManager;
private readonly IEnumerable<IHtmlFilter> _htmlFilters;
private readonly IHtmlFilterProcessor _htmlFilterProcessor;

public ContainerFeedQuery(IContentManager contentManager, IEnumerable<IHtmlFilter> htmlFilters) {
public ContainerFeedQuery(IContentManager contentManager, IHtmlFilterProcessor htmlFilterProcessor) {
_contentManager = contentManager;
_htmlFilters = htmlFilters;
_htmlFilterProcessor = htmlFilterProcessor;
}

public FeedQueryMatch Match(FeedContext context) {
Expand Down Expand Up @@ -55,7 +54,7 @@ public class ContainerFeedQuery : IFeedQueryProvider, IFeedQuery {
return;
}

var inspector = new ItemInspector(container, _contentManager.GetItemMetadata(container), _htmlFilters);
var inspector = new ItemInspector(container, _contentManager.GetItemMetadata(container), _htmlFilterProcessor);
if (context.Format == "rss") {
var link = new XElement("link");
context.Response.Element.SetElementValue("title", inspector.Title);
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
<span class="raw">@Html.Raw(Model.Content.BodyPart.Text)</span>
@using Orchard.Core.Common.Models
@using Orchard.Services

@{
var htmlFilterProcessor = WorkContext.Resolve<IHtmlFilterProcessor>();
var bodyPart = Model.Content.BodyPart as BodyPart;
var bodyText = htmlFilterProcessor.ProcessFilters(bodyPart.Text, bodyPart.GetFlavor(), bodyPart);
}

<span class="raw">@Html.Raw(bodyText)</span>
13 changes: 7 additions & 6 deletions src/Orchard.Web/Modules/Markdown/Services/MarkdownFilter.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
using System;
using Orchard.Services;

namespace Markdown.Services {
public class MarkdownFilter : IHtmlFilter {
public string ProcessContent(string text, string flavor) {
return String.Equals(flavor, "markdown", StringComparison.OrdinalIgnoreCase) ? MarkdownReplace(text) : text;
namespace Markdown.Services
{
public class MarkdownFilter : HtmlFilter {
public override string ProcessContent(string text, HtmlFilterContext context) {
return String.Equals(context.Flavor, "markdown", StringComparison.OrdinalIgnoreCase) ? MarkdownReplace(text) : text;
}

private static string MarkdownReplace(string text) {
if (string.IsNullOrEmpty(text))
return string.Empty;
if (String.IsNullOrEmpty(text))
return String.Empty;

return Markdig.Markdown.ToHtml(text);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
using Orchard.Services;

namespace Orchard.Azure.MediaServices.Services.Rendering {
public class CloudVideoFilter : IHtmlFilter {
public class CloudVideoFilter : HtmlFilter {
private readonly IShapeFactory _shapeFactory;
private readonly IContentManager _contentManager;
private readonly IShapeDisplay _shapeDisplay;
Expand All @@ -23,8 +23,8 @@ public class CloudVideoFilter : IHtmlFilter {
_shapeDisplay = shapeDisplay;
}

public string ProcessContent(string text, string flavor) {
return String.Equals(flavor, "html", StringComparison.OrdinalIgnoreCase) ? ReplaceVideoPlaceholder(text) : text;
public override string ProcessContent(string text, HtmlFilterContext context) {
return String.Equals(context.Flavor, "html", StringComparison.OrdinalIgnoreCase) ? ReplaceVideoPlaceholder(text) : text;
}

private string ReplaceVideoPlaceholder(string text) {
Expand Down

0 comments on commit cf4335e

Please sign in to comment.