Skip to content

Commit

Permalink
Merge branch 'flush'
Browse files Browse the repository at this point in the history
  • Loading branch information
ltrzesniewski committed Apr 6, 2024
2 parents fe6125b + 692d6de commit c22d353
Show file tree
Hide file tree
Showing 12 changed files with 450 additions and 134 deletions.
19 changes: 19 additions & 0 deletions README.md
Expand Up @@ -196,6 +196,25 @@ The `RazorTemplate` base class provides `Render` and `RenderAsync` methods to ex

Templates are stateful and not thread-safe, so it is advised to always create new instances of the templates to render.

### Flushing partial output

By default, the output of a template is buffered while it is executing, then copied to the provided writer when finished. This is necessary for features such as layouts to be supported, but may not always be desired.

The `RazorTemplate` class provides a `FlushAsync` method which will copy the buffered output to the provided `TextWriter` and then flush the writer:

<!-- snippet: TemplateWithFlush.Usage -->
<a id='snippet-templatewithflush.usage'></a>
```cshtml
<div>Lightweight content goes here.</div>
@await FlushAsync()
<div>Slower to render content goes here.</div>
```
<sup><a href='/src/RazorBlade.IntegrationTest/Examples/TemplateWithFlush.cshtml#L2-L6' title='Snippet source file'>snippet source</a> | <a href='#snippet-templatewithflush.usage' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

> [!IMPORTANT]
> Flushing is not compatible with layout usage.
### MSBuild

The source generator will process `RazorBlade` MSBuild items which have the `.cshtml` file extension.
Expand Down
@@ -0,0 +1,6 @@
@inherits RazorBlade.HtmlTemplate
@* begin-snippet: TemplateWithFlush.Usage *@
<div>Lightweight content goes here.</div>
@await FlushAsync()
<div>Slower to render content goes here.</div>
@* end-snippet *@
7 changes: 7 additions & 0 deletions src/RazorBlade.IntegrationTest/PageWithFlush.cshtml
@@ -0,0 +1,7 @@
@inherits RazorBlade.HtmlTemplate
<h2>Hello, world!</h2>
This is the body contents before flushing.
@await FlushAsync()
This is the body contents after flushing.
@await FlushAsync()
This is the body contents after a second flushing.
1 change: 1 addition & 0 deletions src/RazorBlade.IntegrationTest/Program.cs
Expand Up @@ -10,6 +10,7 @@ public static void Main()
WriteTemplate(new TestTemplate { Name = "World" });
WriteTemplate(new TestTemplateWithModel(new FooBarModelClass { Foo = "Foo", Bar = "Bar" }));
WriteTemplate(new PageWithLayout());
WriteTemplate(new PageWithFlush());
}

private static void WriteTemplate(RazorTemplate template)
Expand Down
6 changes: 3 additions & 3 deletions src/RazorBlade.Library/HtmlLayout.cs
Expand Up @@ -21,20 +21,20 @@ async Task<IRazorExecutionResult> IRazorLayout.ExecuteLayoutAsync(IRazorExecutio
try
{
_layoutInput = input;
return await ExecuteAsyncCore(input.CancellationToken);
return await ExecuteAsyncCore(null, input.CancellationToken);
}
finally
{
_layoutInput = null;
}
}

private protected override Task<IRazorExecutionResult> ExecuteAsyncCore(CancellationToken cancellationToken)
private protected override Task<IRazorExecutionResult> ExecuteAsyncCore(TextWriter? targetOutput, CancellationToken cancellationToken)
{
if (_layoutInput is null)
throw new InvalidOperationException(_contentsRequiredErrorMessage);

return base.ExecuteAsyncCore(cancellationToken);
return base.ExecuteAsyncCore(targetOutput, cancellationToken);
}

/// <summary>
Expand Down

0 comments on commit c22d353

Please sign in to comment.