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.