dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.44k stars 10.02k forks source link

TagHelper Extensions: .Prepend() and .WrapContent() #27852

Open Flatts3000 opened 3 years ago

Flatts3000 commented 3 years ago

Forgive me, as I am new to Razor TagHelpers.

When building a tag using a TagHelper, I'm finding myself often wanting to wrap the inner content of the component with an element, a div.container for example.

I've written this extension method, which wraps the tag content in a standard Bootstrap row.

public static void WrapContentInRow(this TagHelperOutput output)
{
    output.PreContent.AppendHtml("<div class=\"row\">");
    output.PostContent.AppendHtml("</div>");
}

The issue comes when I want to wrap the content in more than one element. The following code is an example of the outcome I want. The nav-dropdown-menu tag has two divs which are added by the TagHelper and are "wrapping" the content by prepending the starting tags and appending the ending tags.

Razor:

<nav-dropdown>
    <a href="#">Label</a>
    <nav-dropdown-menu>
        Content
    </nav-dropdown-menu>
</nav-dropdown>

Becomes this raw html:

<li class="nav-item dropdown">
    <a href="#">Label</a>
    <div class="dropdown-menu">
        <div class="container">
            <div class="row">
                Content
            </div>
        </div>
    </div>
</li>

Currently, the way that I see to do this is to do the following (there may be some cleaner ways but I've boiled it down to this simple example):

output.PreContent.Append("<div class=/"container/"><div class=/"row/">");
output.PostContent.Append("</div></div>");

This approach is OK, but it losses some of the benefit of the TagHelper. I would like to be able to do the following:

output.WrapContent(iHtmlContentObj);

or at least be able to create this extension method:

public static void WrapContent(this TagHelperOutput output, TagBuilder wrapper)
{
    output.PreContent.PrependHtml(wrapper.RenderStartTag());
    output.PostContent.AppendHtml(wrapper.RenderEndTag());
}

The extension method uses "PrependHtml()" which doesn't exist to my knowledge. With the implementation of this new method, one would be able to chain the wrapping of the content by multiple divs. Otherwise the ordering of closing or opening tags is incorrect.

The merit of PrependHtml() vs the merit of WrapContent() are separate IMO, and each should be considered on their own.

javiercn commented 3 years ago

@Flatts3000 thanks for contacting us.

We'll gather more feedback on this issue and make a decision in the future.

ghost commented 3 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

Dunc1995 commented 2 years ago

On a broader note, it'd be really nice to have HTML syntax highlighting embedded in the TagHelper files in some fashion, although appreciate this may not be possible. It seems a bit counterintuitive to have to define reusable HTML blocks via string literals and it also makes it difficult to implement nested TagHelpers - I'm not sure if this is by design.