Applying a class to some link text
-
26-06-2021 - |
Question
We've recently added an extension method (string.Highlight(string target)
) to wrap occurences of the target text with <span class="highlighted"></span>
, and are using it for all text displayed on the page.
The initial issue we ran into was that rather than the text being wrapped in the tag, the text was wrapped in plaintext "<span clas..."
. We've managed to resolve this with the exception of text within a link.
<%= Html.ActionLink(linkText.Highlight(word), action) %>
This sticks the text "<span class..."
into the link, which is not what we want. Is there a way to apply our highlighting class to some of the text within the link, or should we forget about it?
The extension method:
public static string Highlight(this string text, this string target)
{
return text.Replace(target, @"<span class=""highlighted"">" + target + "</span>";
}
La solution
You could write a custom ActionLink extension method that doesn't HTML encode the text as the standard helper does:
public static MvcHtmlString UnencodedActionLink(
this HtmlHelper htmlHelper,
string linkText,
string actionName
)
{
var str = UrlHelper.GenerateUrl(null, actionName, null, null, null, null, new RouteValueDictionary(), htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true);
var a = new TagBuilder("a")
{
InnerHtml = !string.IsNullOrEmpty(linkText) ? linkText : string.Empty
};
a.MergeAttribute("href", str);
return MvcHtmlString.Create(a.ToString(TagRenderMode.Normal));
}
and then:
<%= Html.UnencodedActionLink(linkText.Highlight(word), action) %>
or even better:
public static MvcHtmlString HighlightedActionLink(
this HtmlHelper htmlHelper,
string linkText,
string word,
string actionName
)
{
var str = UrlHelper.GenerateUrl(null, actionName, null, null, null, null, new RouteValueDictionary(), htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true);
var a = new TagBuilder("a")
{
InnerHtml = !string.IsNullOrEmpty(linkText) ? linkText.Highlight(word) : string.Empty
};
a.MergeAttribute("href", str);
return MvcHtmlString.Create(a.ToString(TagRenderMode.Normal));
}
and then:
<%= Html.HighlightedActionLink(linkText, word, action) %>
Autres conseils
ActionLink
(and I imagine all of the Html
helper methods) HTML-encodes text for obvious security reasons (preventing XSS vulnerabilities by default).
If all you need to do is apply a CSS class, you can do it directly in the ActionLink
:
<%= Html.ActionLink(word, action, null, new { @class = "highlighted" })%>
Of course, this will apply the class
to the a
rather than use a span
. But then why do you need a span
inside of the a
in the first place when an a
can hold a class attribute as well?