You can create your own tag helpers by implementing ITagHelper
or deriving from the convenience class TagHelper
.
WidgetTagHelper
will target a <widget>
tag.[HtmlTargetElement]
attribute can be used to further control the tag being targettedpublic string Title {get; set;}
can be given a value as <widget title="my title">
[HtmlTargetElement]
and the class name is WidgetBoxTagHelper
, then in Razor you'll write <widget-box></widget-box>
.Process
and ProcessAsync
contain the rendering logic. Both receive a context parameter with information about the current tag being rendered and an output parameter used to customize the rendered result.Any assembly containing custom tag helpers needs to be added to the _ViewImports.cshtml file (Note it is the assembly being registered, not the namespace):
@addTagHelper *, MyAssembly
The following example creates a custom widget tag helper that will target razor markup like:
<widget-box title="My Title">This is my content: @ViewData["Message"]</widget-box>
Which will be rendered as:
<div class="widget-box">
<div class="widget-header">My Title</div>
<div class="widget-body">This is my content: some message</div>
</div>
The coded needed to create such a tag helper is the following:
[HtmlTargetElement("widget-box")]
public class WidgetTagHelper : TagHelper
{
public string Title { get; set; }
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
var outerTag = new TagBuilder("div");
outerTag.Attributes.Add("class", output.TagName);
output.MergeAttributes(outerTag);
output.TagName = outerTag.TagName;
//Create the header
var header = new TagBuilder("div");
header.Attributes.Add("class", "widget-header");
header.InnerHtml.Append(this.Title);
output.PreContent.SetHtmlContent(header);
//Create the body and replace original tag helper content
var body = new TagBuilder("div");
body.Attributes.Add("class", "widget-body");
var originalContents = await output.GetChildContentAsync();
body.InnerHtml.Append(originalContents.GetContent());
output.Content.SetHtmlContent(body);
}
}