Skip to content

Commit 8661d4b

Browse files
committed
Add Templated Razor delegates
1 parent f8d7419 commit 8661d4b

4 files changed

Lines changed: 58 additions & 1 deletion

File tree

src/RazorBlade.Analyzers/RazorBladeSourceGenerator.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ private static RazorCSharpDocument GenerateRazorCode(SourceText sourceText, Inpu
148148
});
149149

150150
cfg.Features.Add(new ErrorOnTagHelperSyntaxTreePass());
151+
152+
cfg.AddTargetExtension(new TemplateTargetExtension { TemplateTypeName = "HelperResult" });
151153
}
152154
);
153155

src/RazorBlade.IntegrationTest/TestTemplate.cshtml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@using RazorBlade.IntegrationTest
1+
@using System
22
@inherits RazorBlade.HtmlTemplate
33

44
<b>Hello, @Name!</b>
@@ -12,6 +12,13 @@
1212
@br
1313
@Html.Raw("<br>")
1414

15+
@{
16+
Func<string, IEncodedContent> bold = @<b>@item</b>;
17+
}
18+
19+
@bold("Bold text")
20+
@bold("Other bold text")
21+
1522
@(new Footer())
1623

1724
@functions {

src/RazorBlade.Library.Tests/RazorTemplateTests.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,30 @@ public async Task should_buffer_output_until_flushed()
233233
output.ToString().ShouldEqual("foo bar baz");
234234
}
235235

236+
[Test]
237+
public void should_execute_templated_delegate()
238+
{
239+
var template = new Template(t =>
240+
{
241+
Func<object, object> bold = item => new RazorTemplate.HelperResult(writer =>
242+
{
243+
t.PushWriter(writer);
244+
t.WriteLiteral("<b>");
245+
t.Write(item);
246+
t.WriteLiteral("</b>");
247+
t.PopWriter();
248+
return Task.CompletedTask;
249+
}
250+
);
251+
252+
t.Write(bold("Bold text"));
253+
t.WriteLiteral(" - ");
254+
t.Write(bold("Other bold text"));
255+
});
256+
257+
template.Render().ShouldEqual("<b>Bold text</b> - <b>Other bold text</b>");
258+
}
259+
236260
private class Template(Func<Template, Task> executeAction) : RazorTemplate
237261
{
238262
public Template(Action<Template> executeAction)
@@ -252,6 +276,10 @@ protected internal override async Task ExecuteAsync()
252276

253277
protected internal override void Write(object? value)
254278
{
279+
if (value is IEncodedContent encodedContent)
280+
encodedContent.WriteTo(Output);
281+
else
282+
WriteLiteral(value?.ToString());
255283
}
256284

257285
protected internal override void BeginWriteAttribute(string name, string prefix, int prefixOffset, string suffix, int suffixOffset, int attributeValuesCount)

src/RazorBlade.Library/RazorTemplate.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,4 +521,24 @@ public void WriteTo(TextWriter textWriter)
521521
public override string ToString()
522522
=> Output.ToString();
523523
}
524+
525+
/// <summary>
526+
/// Represents a deferred write operation.
527+
/// </summary>
528+
[PublicAPI]
529+
protected internal class HelperResult : IEncodedContent
530+
{
531+
private readonly Func<TextWriter, Task> _action;
532+
533+
/// <summary>
534+
/// Creates a deferred operation.
535+
/// </summary>
536+
/// <param name="action">The action to execute.</param>
537+
public HelperResult(Func<TextWriter, Task> action)
538+
=> _action = action;
539+
540+
/// <inheritdoc />
541+
public void WriteTo(TextWriter textWriter)
542+
=> _action.Invoke(textWriter).GetAwaiter().GetResult();
543+
}
524544
}

0 commit comments

Comments
 (0)