Home > Blockchain >  Razor template/component solution that supports child Razor markup
Razor template/component solution that supports child Razor markup

Time:12-17

Is there a template/component solution in ASP.NET Core Razor, that supports inner Razor markup?

Here's a use case:

1. Say I have some repetitive markup for example "a div with nice borders, shadows and two buttons at the bottom"

2. Obviously this markup has a common "header" and a "footer" in the HTML code

3. I need to pass arbitrary Razor markup to insert between header and footer. Not just a model object - but some actual markup that will be rendered between header and footer. I can't use foreach because this markup is different every time - it can be text-content, a form, an image, or some complicated Razor-rendered stuff.

Basically I'm looking for a "Surround this Razor with more Razor" templating solution

Something like:

@{
    //this function renders my beautiful box
    Func<dynamic, IHtmlContent> myFunction = @<div >
        @item
    </div>;
}

<!-- and then I call it passing some Razor as input -->
@myFunction(
    <ul>
        <li>@SomeRazorMethod()</li>
    </ul>

);

Something like a Layout - but the one I can use multiple times on the same page.

Is there anything like that? This is a pretty common componentizing tool - "wrap my markup with other markup" - that is present in other templating engines (React, Vue, etc), but apparently not in Razor.

Just to be clear: I'm looking for a Razor-based solution, not a C#-based one. So that my header-footer markup stays in markup files (.cshtml), not in C# files that will have hard-coded HTML magic strings.

CodePudding user response:

You can use Partial Pages or Views which are Razor files containing snippets of HTML and server-side code to be included in any number of pages or layouts.

Just like standard Razor pages, partial pages support the @model directive specifying the type for the partial's data model. All of the rendering methods have overloaded versions that take a model to be consumed in the partial.

CodePudding user response:

Based on your example, this might help.

@functions {
    public static IHtmlContent MyBox(dynamic item, Func<dynamic, IHtmlContent> template)
    {
        var html = new HtmlContentBuilder();

        html.AppendHtml("<div class='bestcss'>");
        html.AppendHtml(template(item));
        html.AppendHtml("</div>");

        return html;
    }
}

@MyBox(null, @<div class='innercss'>@(10 == 12 ? "MyTest Equals" : "No Equal") hello</div>)

And if you like to pass modeldata, it will be:

@MyBox(customerdata, @<div class='innercss'>@(10 == 12 ? "MyTest Equals" : "No Equal") hello @item.FirstName</div>)

I have used some arbitrary if condition for testing.

  • Related