-
Notifications
You must be signed in to change notification settings - Fork 10k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Razor Templating Improvements #4988
Comments
I'm still not 100% clear what the difference is between this and the I love templated tag helpers as a way to have cleaner inline templates. That original syntax was awful (I say having participated in designing it ;P) 👍 🎉 💯 |
Sounds very nice! No more painting over the telephone! |
Im loving the sound of this feature, this would be very useful for creating html report solutions using templates; it would be great if the feature could also accept IQueryable outputting to a Stream asynchronously in cases where large datasets and outputs are needed to be persisted or downloaded to a client as a file. |
First: Thank god the previous feature was actually mentioned. I thought I'd dreamed it all up. I've almost never seen it used or mentioned aside from Phil Haack's post and it is the worst possible syntax to Google, maybe aside from the This sounds good even though I agree with @anurse wondering what the difference between this and helpers are. Since helpers were supposed to go in App_Code, I understand the desire to make a distinction though. I think the magical uses of
That said, I understand that the syntax for declaring a variable name in an HTML attribute is awkward and that there's no really Razor-y way to do it - but you could argue that using the names of the templates are too. |
@JesperTreetop not sure I agree with the
the item is obtained from the foreach of the items; which as the example shows is an IEnumerable and after all it's up to you as the template developer to name the parameter/variables; however that said I do think there is a error where
should be
having said that I'm thinking why doesn't the razor template use the keyword of model the same as a razor view? |
@grahamehorner In this example from the original post:
...that's where |
@JesperTreetop you're right regarding the generated |
Inspired by the lovely spark view engine. |
or even something like
where by you tell the template engine the model variable name and the type or interface which it implements; then inside the template the tag of foreach with the item-type, item-name and in allows the developer to inform the template engine of what/how to consume/process the model instance its was supplied. |
As always when Razor offers easy access to C# and Tag Helpers are a valuable addition because they're a way of making the declarative, domain specific parts and the conceptual templates look more like markup. Having tags that just enable C# code to be written as HTML would defeat the purpose, in my opinion. If you want to write a foreach, just write The most Razor-like thing that I can imagine is to just say:
...like in the |
@JesperTreetop yeah lolz; loads of options anything is possible ;) |
We should take the improvement from here: aspnet/Razor#132 as part of this work |
It is quite unfortunate that this topic is not followed up as with the removal of The following snippet is the closest what I could write to "well-formed" syntax in Razor: @{
IHtmlContent MyTemplate(string param1, double param2)
{
if (param2 < 0.5)
{
return @<text>@param1</text>;
}
else
{
return @<text>@param1.ToUpper()</text>;
}
}
}
@MyTemplate("a", 1)
@MyTemplate("a", 0) But the output expression translates to a lambda instead of a simple HelperResult: IHtmlContent MyTemplate(string param1, double param2)
{
if (param2 < 0.5)
{
return item => new global::Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_template_writer) => {
PushWriter(__razor_template_writer);
BeginContext(6257, 6, false);
Write(param1);
EndContext();
PopWriter();
});
}
else
{
return item => new global::Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_template_writer) => {
PushWriter(__razor_template_writer);
BeginContext(6336, 16, false);
Write(param1.ToUpper());
EndContext();
PopWriter();
});
}
} |
Closing as this issue is outdated. Things which matter will come back up again. |
Introduction
Today, Razor doesn't expose much functionality to enable app developers to leverage Razor templates at runtime. That is, Razor is a templating language, but it doesn't have many features that allow the developer to use templates written in Razor as a first-class primitive in view/page composition.
The one feature that does exist is that of "Templated Razor Delegates" (or "Template Expressions"), which allow for fragments of Razor to be captured as delegates and thus passed into functions, including HTML Helpers, and then executed to produce HTML output. E.g. in the following code, the block
@<li>@item</li>
is the "template expression".Helpers.cs
View.cshtml
This feature has a number of limitations that if addressed, and expanded upon, can provide a more powerful and expressive set of first-class templating features in Razor.
Support Declarative Template Authoring & Re-use via an
@template
DirectiveRather than trying to add new features to the existing template expressions feature, which could be limited by issues of backwards compatibility, we'll add a new directive to support declaratively creating Razor templates in CSHTML files:
This would be roughly equivalent to (and thus generate):
This could be declared in any Razor file, including in
_ViewImports.cshtml
in an MVC application, to allow for easy re-use across the application.The templates could then be executed directly in Razor files. In this way they're very similar to the
@helper
directive from ASP.NET Web Pages:They can also be passed in to other methods that accept the template delegate signature:
Support Truly Async Template Expressions
Currently, while the delegates generated by template expressions support async statements, they are always evaluated synchronously (i.e. the calling thread is blocked while the delegate is executed). This logic is actually in MVC, so we'd need to make some changes to the contract between Razor and a Razor host, or limit this functionality to the new
@template
directive (see above).This would be roughly equivalent to (and thus generate):
Support Multiple Arguments
Template expressions are currently limited to a single argument. We should extend this to support multiple arguments when using the
@template
directive, e.g.:This would be roughly equivalent to (and thus generate):
The templates could then be executed directly in Razor files. In this way they're very similar to the
@helper
directive from ASP.NET Web Pages:They can also be passed in to other methods that accept the template delegate signature:
Support Templated Tag Helpers
We should extend Tag Helpers to make working with templates a first-class experience. Binding templates to properties as well as treating the content or even the entire element of a Tag Helper as a template should be possible.
Tag Helper with content as a template
Tag Helper with template properties
TODO: Update with some details about integration with #791
Support Template Compilation & Packaging
To enable sharing of declared templates across projects without having to restore to writing them manually in C#, we should build a tool that allows compiling templates from CSHTML files directly to assemblies/NuGet packages. This could be a project tool that works with the .NET Core CLI (e.g.
dotnet razor compile-templates
) or a Roslyn compilation extension/module that allows for templates (and potentially other Razor primitives) to be compiled as part of project compilation.The text was updated successfully, but these errors were encountered: