diff --git a/Fluid/FluidTemplateExtensions.String.cs b/Fluid/FluidTemplateExtensions.String.cs new file mode 100644 index 00000000..6f1366c2 --- /dev/null +++ b/Fluid/FluidTemplateExtensions.String.cs @@ -0,0 +1,50 @@ +using Fluid.Utils; +using System.Runtime.CompilerServices; +using System.Text.Encodings.Web; + +namespace Fluid +{ + public static partial class FluidTemplateExtensions + { + /// + /// Renders the specified Fluid template asynchronously using a new TemplateContext. + /// + /// The Fluid template to render. + /// A ValueTask that represents the asynchronous rendering operation. The task result contains the rendered template as a string. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ValueTask RenderAsync(this IFluidTemplate template) + { + return RenderAsync(template, new TemplateContext()); + } + + /// + /// Renders the specified Fluid template asynchronously using the provided context and a default text encoder. + /// + /// The Fluid template to render. + /// The context to use for rendering the template. + /// A ValueTask that represents the asynchronous rendering operation. The task result contains the rendered template as a string. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ValueTask RenderAsync(this IFluidTemplate template, TemplateContext context) + { + return RenderAsync(template, context, NullEncoder.Default); + } + + /// + /// Renders the specified Fluid template asynchronously using the provided context, encoder, and isolation settings. + /// + /// The Fluid template to render. + /// The context to use for rendering the template. + /// The text encoder to use for encoding the output. + /// A boolean value indicating whether to isolate the context during rendering. + /// A ValueTask that represents the asynchronous rendering operation. The task result contains the rendered template as a string. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static async ValueTask RenderAsync(this IFluidTemplate template, TemplateContext context, TextEncoder encoder, bool isolateContext = true) + { + using var sb = StringBuilderPool.GetInstance(); + using var writer = new StringWriter(sb.Builder); + + await RenderAsync(template, writer, context, encoder, isolateContext); + return sb.ToString(); + } + } +} diff --git a/Fluid/FluidTemplateExtensions.Sync.cs b/Fluid/FluidTemplateExtensions.Sync.cs new file mode 100644 index 00000000..e65c87a8 --- /dev/null +++ b/Fluid/FluidTemplateExtensions.Sync.cs @@ -0,0 +1,64 @@ +using System.Runtime.CompilerServices; +using System.Text.Encodings.Web; + +namespace Fluid +{ + public static partial class FluidTemplateExtensions + { + /// + /// Renders the template to a string. + /// + /// The template to render. + /// The rendered template as a string. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Render(this IFluidTemplate template) + { + return Render(template, new TemplateContext()); + } + + /// + /// Renders the template to a string using the specified context. + /// + /// The template to render. + /// The context to use for rendering. + /// The rendered template as a string. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Render(this IFluidTemplate template, TemplateContext context) + { + return Render(template, context, NullEncoder.Default); + } + + /// + /// Renders the template to the specified text writer using the specified context and text encoder. + /// + /// The template to render. + /// The context to use for rendering. + /// The text encoder to use for rendering. + /// A boolean value indicating whether to isolate the context during rendering. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Render(this IFluidTemplate template, TemplateContext context, TextEncoder encoder, bool isolateContext = true) + { + var task = RenderAsync(template, context, encoder, isolateContext); + return task.IsCompletedSuccessfully ? task.Result : task.AsTask().GetAwaiter().GetResult(); + } + + /// + /// Renders the template to the specified text writer using the specified context and text encoder. + /// This method is obsolete and will be removed in a future version. + /// + /// The template to render. + /// The context to use for rendering. + /// The text encoder to use for rendering. + /// The text writer to write the rendered template to. + [Obsolete("Use Render(this IFluidTemplate template, TextWriter writer, TemplateContext context, TextEncoder encoder) instead. This method will be removed in a future version.")] + public static void Render(this IFluidTemplate template, TemplateContext context, TextEncoder encoder, TextWriter writer) + { + var task = RenderAsync(template, writer, context, encoder); + + if (!task.IsCompletedSuccessfully) + { + task.AsTask().GetAwaiter().GetResult(); + } + } + } +} diff --git a/Fluid/FluidTemplateExtensions.cs b/Fluid/FluidTemplateExtensions.cs index 61e4fc08..329957a4 100644 --- a/Fluid/FluidTemplateExtensions.cs +++ b/Fluid/FluidTemplateExtensions.cs @@ -1,37 +1,53 @@ -using Fluid.Utils; using System.Runtime.CompilerServices; using System.Text.Encodings.Web; namespace Fluid { - public static class FluidTemplateExtensions + public static partial class FluidTemplateExtensions { + /// + /// Renders a Fluid template asynchronously to a specified text writer. It uses a default template context for + /// rendering. + /// + /// Specifies the fluid template to be rendered. + /// Defines the output destination for the rendered content. + /// Returns a ValueTask representing the asynchronous rendering operation. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ValueTask RenderAsync(this IFluidTemplate template, TemplateContext context) + public static ValueTask RenderAsync(this IFluidTemplate template, TextWriter textWriter) { - return template.RenderAsync(context, NullEncoder.Default); + return template.RenderAsync(textWriter, new TemplateContext()); } + /// + /// Renders a Fluid template asynchronously to a specified text writer using a default encoder. + /// + /// Represents the template to be rendered. + /// Used to write the rendered output of the template. + /// Provides the context for rendering the template. + /// Returns a ValueTask representing the asynchronous operation. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Render(this IFluidTemplate template, TemplateContext context, TextEncoder encoder) + public static ValueTask RenderAsync(this IFluidTemplate template, TextWriter textWriter, TemplateContext context) { - var task = template.RenderAsync(context, encoder); - return task.IsCompletedSuccessfully ? task.Result : task.AsTask().GetAwaiter().GetResult(); + return template.RenderAsync(textWriter, context, NullEncoder.Default); } + /// + /// Renders a Fluid template asynchronously to a specified text writer using a given context and encoder. + /// + /// Specifies the fluid template to be rendered. + /// Defines the output destination for the rendered content. + /// Provides the context in which the template is evaluated. + /// Handles the encoding of the output content. + /// Indicates whether to evaluate the template in a separate context scope. + /// Returns a ValueTask representing the asynchronous operation. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Render(this IFluidTemplate template, TemplateContext context, TextEncoder encoder, TextWriter writer) + public static async ValueTask RenderAsync(this IFluidTemplate template, TextWriter textWriter, TemplateContext context, TextEncoder encoder, bool isolateContext = true) { - var task = template.RenderAsync(writer, encoder, context); - if (!task.IsCompletedSuccessfully) + if (textWriter == null) { - task.AsTask().GetAwaiter().GetResult(); + ExceptionHelper.ThrowArgumentNullException(nameof(textWriter)); } - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static async ValueTask RenderAsync(this IFluidTemplate template, TemplateContext context, TextEncoder encoder, bool isolateContext = true) - { if (context == null) { ExceptionHelper.ThrowArgumentNullException(nameof(context)); @@ -42,9 +58,6 @@ public static async ValueTask RenderAsync(this IFluidTemplate template, ExceptionHelper.ThrowArgumentNullException(nameof(template)); } - var sb = StringBuilderPool.GetInstance(); - var writer = new StringWriter(sb.Builder); - // A template is evaluated in a child scope such that the provided TemplateContext is immutable if (isolateContext) { @@ -53,15 +66,13 @@ public static async ValueTask RenderAsync(this IFluidTemplate template, try { - await template.RenderAsync(writer, encoder, context); + await template.RenderAsync(textWriter, encoder, context); - writer.Flush(); - return sb.ToString(); + textWriter.Flush(); } finally { - sb.Dispose(); - writer.Dispose(); + textWriter.Dispose(); if (isolateContext) { @@ -69,25 +80,5 @@ public static async ValueTask RenderAsync(this IFluidTemplate template, } } } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Render(this IFluidTemplate template, TemplateContext context) - { - var task = template.RenderAsync(context); - return task.IsCompletedSuccessfully ? task.Result : task.AsTask().GetAwaiter().GetResult(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ValueTask RenderAsync(this IFluidTemplate template) - { - return template.RenderAsync(new TemplateContext()); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string Render(this IFluidTemplate template) - { - var task = template.RenderAsync(); - return task.IsCompletedSuccessfully ? task.Result : task.AsTask().GetAwaiter().GetResult(); - } } }