From be3b5e5f5588ab5f11c43096e1611f827235b1b7 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Mon, 29 Mar 2021 14:25:38 -0700 Subject: [PATCH 01/11] MapAction view engine example --- .../Fluid.MapActionSample.csproj | 15 ++++ Fluid.MapActionSample/Program.cs | 42 ++++++++++ Fluid.MapActionSample/Views/_layout.liquid | 34 ++++++++ Fluid.MapActionSample/Views/_viewstart.liquid | 2 + Fluid.MapActionSample/Views/component.liquid | 1 + Fluid.MapActionSample/Views/index.liquid | 10 +++ Fluid.MapActionSample/appsettings.json | 9 +++ Fluid.MapActionViewEngine/ActionViewResult.cs | 77 +++++++++++++++++++ .../Directory.Build.props | 10 +++ .../Fluid.MapActionViewEngine.csproj | 21 +++++ .../FluidViewEngineOptionsSetup.cs | 24 ++++++ .../MapActionViewEngineBuilderExtensions.cs | 35 +++++++++ Fluid.sln | 14 +++- 13 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 Fluid.MapActionSample/Fluid.MapActionSample.csproj create mode 100644 Fluid.MapActionSample/Program.cs create mode 100644 Fluid.MapActionSample/Views/_layout.liquid create mode 100644 Fluid.MapActionSample/Views/_viewstart.liquid create mode 100644 Fluid.MapActionSample/Views/component.liquid create mode 100644 Fluid.MapActionSample/Views/index.liquid create mode 100644 Fluid.MapActionSample/appsettings.json create mode 100644 Fluid.MapActionViewEngine/ActionViewResult.cs create mode 100644 Fluid.MapActionViewEngine/Directory.Build.props create mode 100644 Fluid.MapActionViewEngine/Fluid.MapActionViewEngine.csproj create mode 100644 Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs create mode 100644 Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs diff --git a/Fluid.MapActionSample/Fluid.MapActionSample.csproj b/Fluid.MapActionSample/Fluid.MapActionSample.csproj new file mode 100644 index 00000000..736c4664 --- /dev/null +++ b/Fluid.MapActionSample/Fluid.MapActionSample.csproj @@ -0,0 +1,15 @@ + + + + net6.0 + Exe + $(NoWarn);NU5104 + false + 9 + + + + + + + diff --git a/Fluid.MapActionSample/Program.cs b/Fluid.MapActionSample/Program.cs new file mode 100644 index 00000000..35f3befb --- /dev/null +++ b/Fluid.MapActionSample/Program.cs @@ -0,0 +1,42 @@ +using Fluid.MapActionViewEngine; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using System; + +using var host = Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.ConfigureServices(services => + { + services.AddFluid(); + }); + + webBuilder.Configure(app => + { + app.UseRouting(); + + app.UseEndpoints(endpoints => + { + IResult ViewAsync() + { + var todo = new Todo(1, "Go back to work!", false); + return new ActionViewResult("index", todo); + }; + + endpoints.MapGet("/", (Func)ViewAsync); + + }); + + }); + }) + .Build(); + +await host.StartAsync(); + +await host.WaitForShutdownAsync(); + +record Todo(int Id, string Name, bool IsComplete); \ No newline at end of file diff --git a/Fluid.MapActionSample/Views/_layout.liquid b/Fluid.MapActionSample/Views/_layout.liquid new file mode 100644 index 00000000..49c548fe --- /dev/null +++ b/Fluid.MapActionSample/Views/_layout.liquid @@ -0,0 +1,34 @@ + + + + + + + + + + + + Hello, world! + + + +
+

Title from the layout

+
+

+ {% renderbody %} + + {% include 'component', x: 1, y:2 %} + +

+
+
+ +
+	{% rendersection footer %}
+	
+ + + + \ No newline at end of file diff --git a/Fluid.MapActionSample/Views/_viewstart.liquid b/Fluid.MapActionSample/Views/_viewstart.liquid new file mode 100644 index 00000000..dabda0f3 --- /dev/null +++ b/Fluid.MapActionSample/Views/_viewstart.liquid @@ -0,0 +1,2 @@ +{% layout '_Layout' %} +From /Views/_ViewStart.liquid diff --git a/Fluid.MapActionSample/Views/component.liquid b/Fluid.MapActionSample/Views/component.liquid new file mode 100644 index 00000000..fd717b32 --- /dev/null +++ b/Fluid.MapActionSample/Views/component.liquid @@ -0,0 +1 @@ +
Using a component {{ x }} + {{ y }} = {{ x | plus: y }}
\ No newline at end of file diff --git a/Fluid.MapActionSample/Views/index.liquid b/Fluid.MapActionSample/Views/index.liquid new file mode 100644 index 00000000..90858060 --- /dev/null +++ b/Fluid.MapActionSample/Views/index.liquid @@ -0,0 +1,10 @@ +
+Hello World from the body + +Name: {{ Name }}
+IsComplete: {{ IsComplete}} +
+ +{% section footer %} +Hello from the footer section +{% endsection %} diff --git a/Fluid.MapActionSample/appsettings.json b/Fluid.MapActionSample/appsettings.json new file mode 100644 index 00000000..c9294ca4 --- /dev/null +++ b/Fluid.MapActionSample/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/Fluid.MapActionViewEngine/ActionViewResult.cs b/Fluid.MapActionViewEngine/ActionViewResult.cs new file mode 100644 index 00000000..bb29e9bf --- /dev/null +++ b/Fluid.MapActionViewEngine/ActionViewResult.cs @@ -0,0 +1,77 @@ +using Fluid.ViewEngine; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using System.IO; +using System.Threading.Tasks; + +namespace Fluid.MapActionViewEngine +{ + public class ActionViewResult : IResult + { + private readonly string _viewName; + private readonly string _area; + private readonly object _model; + + public ActionViewResult(string viewName) + { + _viewName = viewName; + _model = new object(); + } + + public ActionViewResult(string viewName, object model) + { + _viewName = viewName; + _model = model; + } + + public ActionViewResult(string viewName, string area, object model) + { + _viewName = viewName; + _area = area; + _model = model; + } + + public string ContentType { get; set; } = "text/html"; + + public async Task ExecuteAsync(HttpContext httpContext) + { + var fluidViewRenderer = httpContext.RequestServices.GetService(); + var options = httpContext.RequestServices.GetService>().Value; + + var viewPath = LocatePageFromViewLocations(_viewName, _area, options); + + if (viewPath == null) + { + httpContext.Response.StatusCode = 404; + return; + } + + httpContext.Response.StatusCode = 200; + httpContext.Response.ContentType = ContentType; + + await using (var sw = new StreamWriter(httpContext.Response.Body)) + { + await fluidViewRenderer.RenderViewAsync(sw, viewPath, _model); + } + } + + private string LocatePageFromViewLocations(string viewName, string area, FluidViewEngineOptions options) + { + var fileProvider = options.ViewsFileProvider; + + foreach (var location in options.ViewLocationFormats) + { + var viewPath = string.Format(location, viewName, area); + var fileInfo = fileProvider.GetFileInfo(viewPath); + + if (fileInfo.Exists) + { + return viewPath; + } + } + + return null; + } + } +} diff --git a/Fluid.MapActionViewEngine/Directory.Build.props b/Fluid.MapActionViewEngine/Directory.Build.props new file mode 100644 index 00000000..a116cda4 --- /dev/null +++ b/Fluid.MapActionViewEngine/Directory.Build.props @@ -0,0 +1,10 @@ + + + + Fluid.MapActionViewEngine + Fluid.MapActionViewEngine is a view engine for ASP.NET Core Map Actions based on the Liquid markup. + + + + + diff --git a/Fluid.MapActionViewEngine/Fluid.MapActionViewEngine.csproj b/Fluid.MapActionViewEngine/Fluid.MapActionViewEngine.csproj new file mode 100644 index 00000000..348afc5b --- /dev/null +++ b/Fluid.MapActionViewEngine/Fluid.MapActionViewEngine.csproj @@ -0,0 +1,21 @@ + + + + net6.0 + 9 + true + logo_64x64.png + + + + + + + + + + + + + + diff --git a/Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs b/Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs new file mode 100644 index 00000000..0ae78b92 --- /dev/null +++ b/Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs @@ -0,0 +1,24 @@ +using Fluid.ViewEngine; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Options; + +namespace Fluid.MapActionViewEngine +{ + public class FluidViewEngineOptionsSetup : ConfigureOptions + { + public FluidViewEngineOptionsSetup(IWebHostEnvironment webHostEnvironment) + : base(options => + { + //options.IncludesFileProvider = new FileProviderMapper(webHostEnvironment.ContentRootFileProvider, "Views"); + //options.ViewsFileProvider = new FileProviderMapper(webHostEnvironment.ContentRootFileProvider, "Views"); + options.IncludesFileProvider = webHostEnvironment.ContentRootFileProvider; + options.ViewsFileProvider = webHostEnvironment.ContentRootFileProvider; + options.ViewLocationFormats.Add("Views/{0}" + Constants.ViewExtension); + options.ViewLocationFormats.Add("Views/{1}/{0}" + Constants.ViewExtension); + options.ViewLocationFormats.Add("Views/Shared/{0}" + Constants.ViewExtension); + options.TemplateOptions.MemberAccessStrategy = UnsafeMemberAccessStrategy.Instance; + }) + { + } + } +} diff --git a/Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs b/Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs new file mode 100644 index 00000000..0f92af51 --- /dev/null +++ b/Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs @@ -0,0 +1,35 @@ +using Fluid.ViewEngine; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using System; + +namespace Fluid.MapActionViewEngine +{ + public static class MapActionViewEngineBuilderExtensions + { + public static IServiceCollection AddFluid(this IServiceCollection services, Action setupAction = null) + { + if (services == null) + { + throw new ArgumentNullException(nameof(services)); + } + + services.AddOptions(); + services.AddTransient, FluidViewEngineOptionsSetup>(); + + if (setupAction != null) + { + services.Configure(setupAction); + } + + services.AddSingleton(sp => + { + var options = sp.GetRequiredService>().Value; + return new FluidViewRenderer(options); + }); + + return services; + + } + } +} diff --git a/Fluid.sln b/Fluid.sln index d33875eb..0ccf7f45 100644 --- a/Fluid.sln +++ b/Fluid.sln @@ -23,7 +23,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Files", "Files", "{BE5EF08E README.md = README.md EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fluid.ViewEngine", "Fluid.ViewEngine\Fluid.ViewEngine.csproj", "{3510D4C5-8328-4425-B2F1-B8591E85B965}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fluid.ViewEngine", "Fluid.ViewEngine\Fluid.ViewEngine.csproj", "{3510D4C5-8328-4425-B2F1-B8591E85B965}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fluid.MapActionSample", "Fluid.MapActionSample\Fluid.MapActionSample.csproj", "{03BE4428-3251-4115-93E4-C488E4249FB3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fluid.MapActionViewEngine", "Fluid.MapActionViewEngine\Fluid.MapActionViewEngine.csproj", "{0ACE7D6B-AC02-48D5-875F-56B576A0DE54}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -55,6 +59,14 @@ Global {3510D4C5-8328-4425-B2F1-B8591E85B965}.Debug|Any CPU.Build.0 = Debug|Any CPU {3510D4C5-8328-4425-B2F1-B8591E85B965}.Release|Any CPU.ActiveCfg = Release|Any CPU {3510D4C5-8328-4425-B2F1-B8591E85B965}.Release|Any CPU.Build.0 = Release|Any CPU + {03BE4428-3251-4115-93E4-C488E4249FB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {03BE4428-3251-4115-93E4-C488E4249FB3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {03BE4428-3251-4115-93E4-C488E4249FB3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {03BE4428-3251-4115-93E4-C488E4249FB3}.Release|Any CPU.Build.0 = Release|Any CPU + {0ACE7D6B-AC02-48D5-875F-56B576A0DE54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0ACE7D6B-AC02-48D5-875F-56B576A0DE54}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0ACE7D6B-AC02-48D5-875F-56B576A0DE54}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0ACE7D6B-AC02-48D5-875F-56B576A0DE54}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From d78f79a4ab037fc2e019d0d033a3d2c24532e2d6 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Mon, 29 Mar 2021 14:35:07 -0700 Subject: [PATCH 02/11] Introduce net6.0 dependency --- .github/workflows/build.yml | 5 +++++ .github/workflows/publish.yml | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3e2fcccf..00a65935 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,6 +35,11 @@ jobs: uses: actions/setup-dotnet@v1 with: dotnet-version: 5.0.* + - name: Setup dotnet 6.0 + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 6.0.100-preview.4.21178.1 + - name: Test run: dotnet test --configuration Release - name: Test - Compiled diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b06a5a55..d79ec7b6 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,11 +18,11 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: - dotnet-version: 5.0.* + dotnet-version: 6.0.100-preview.4.21178.1 - name: Install dependencies run: dotnet restore - name: Test - run: dotnet test -c Release --framework net5.0 + run: dotnet test -c Release --framework net6.0 - name: Pack with dotnet run: | arrTag=(${GITHUB_REF//\// }) From a372ad0f7cab44f2697cba13be9faa4678449bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Mon, 29 Mar 2021 14:29:49 -0700 Subject: [PATCH 03/11] Update FluidViewEngineOptionsSetup.cs --- Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs b/Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs index 0ae78b92..7bb64368 100644 --- a/Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs +++ b/Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs @@ -9,8 +9,6 @@ public class FluidViewEngineOptionsSetup : ConfigureOptions { - //options.IncludesFileProvider = new FileProviderMapper(webHostEnvironment.ContentRootFileProvider, "Views"); - //options.ViewsFileProvider = new FileProviderMapper(webHostEnvironment.ContentRootFileProvider, "Views"); options.IncludesFileProvider = webHostEnvironment.ContentRootFileProvider; options.ViewsFileProvider = webHostEnvironment.ContentRootFileProvider; options.ViewLocationFormats.Add("Views/{0}" + Constants.ViewExtension); From 458c32b4368e3174365bd6e7b5ab0719957a78aa Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 18 Aug 2021 16:33:48 -0700 Subject: [PATCH 04/11] Update minimal APIs support --- .github/workflows/build.yml | 2 +- .github/workflows/publish.yml | 2 +- .../Fluid.MapActionSample.csproj | 2 +- Fluid.MapActionSample/Program.cs | 62 ++++++------------- Fluid.MapActionViewEngine/ActionViewResult.cs | 10 +-- .../Fluid.MapActionViewEngine.csproj | 1 + Fluid.MapActionViewEngine/LiquidResults.cs | 22 +++++++ .../MapActionViewEngineBuilderExtensions.cs | 8 +-- 8 files changed, 52 insertions(+), 57 deletions(-) create mode 100644 Fluid.MapActionViewEngine/LiquidResults.cs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 00a65935..52709124 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,7 @@ jobs: - name: Setup dotnet 6.0 uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.100-preview.4.21178.1 + dotnet-version: 6.0.* - name: Test run: dotnet test --configuration Release diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d79ec7b6..e86f9c8c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,7 +18,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.100-preview.4.21178.1 + dotnet-version: 6.0.* - name: Install dependencies run: dotnet restore - name: Test diff --git a/Fluid.MapActionSample/Fluid.MapActionSample.csproj b/Fluid.MapActionSample/Fluid.MapActionSample.csproj index 736c4664..69e0b504 100644 --- a/Fluid.MapActionSample/Fluid.MapActionSample.csproj +++ b/Fluid.MapActionSample/Fluid.MapActionSample.csproj @@ -5,7 +5,7 @@ Exe $(NoWarn);NU5104 false - 9 + preview diff --git a/Fluid.MapActionSample/Program.cs b/Fluid.MapActionSample/Program.cs index 35f3befb..a16a122d 100644 --- a/Fluid.MapActionSample/Program.cs +++ b/Fluid.MapActionSample/Program.cs @@ -1,42 +1,20 @@ -using Fluid.MapActionViewEngine; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using System; - -using var host = Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.ConfigureServices(services => - { - services.AddFluid(); - }); - - webBuilder.Configure(app => - { - app.UseRouting(); - - app.UseEndpoints(endpoints => - { - IResult ViewAsync() - { - var todo = new Todo(1, "Go back to work!", false); - return new ActionViewResult("index", todo); - }; - - endpoints.MapGet("/", (Func)ViewAsync); - - }); - - }); - }) - .Build(); - -await host.StartAsync(); - -await host.WaitForShutdownAsync(); - -record Todo(int Id, string Name, bool IsComplete); \ No newline at end of file +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddFluid(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. + +app.UseRouting(); + +app.MapGet("/", () => +{ + return LiquidResults.View("index", new Todo(1, "Go back to work!", false)); +}); + +app.Run(); + +record Todo(int Id, string Name, bool IsComplete); diff --git a/Fluid.MapActionViewEngine/ActionViewResult.cs b/Fluid.MapActionViewEngine/ActionViewResult.cs index bb29e9bf..4c7eb71d 100644 --- a/Fluid.MapActionViewEngine/ActionViewResult.cs +++ b/Fluid.MapActionViewEngine/ActionViewResult.cs @@ -2,8 +2,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -using System.IO; -using System.Threading.Tasks; namespace Fluid.MapActionViewEngine { @@ -50,13 +48,11 @@ public async Task ExecuteAsync(HttpContext httpContext) httpContext.Response.StatusCode = 200; httpContext.Response.ContentType = ContentType; - await using (var sw = new StreamWriter(httpContext.Response.Body)) - { - await fluidViewRenderer.RenderViewAsync(sw, viewPath, _model); - } + await using var sw = new StreamWriter(httpContext.Response.Body); + await fluidViewRenderer.RenderViewAsync(sw, viewPath, _model); } - private string LocatePageFromViewLocations(string viewName, string area, FluidViewEngineOptions options) + private static string LocatePageFromViewLocations(string viewName, string area, FluidViewEngineOptions options) { var fileProvider = options.ViewsFileProvider; diff --git a/Fluid.MapActionViewEngine/Fluid.MapActionViewEngine.csproj b/Fluid.MapActionViewEngine/Fluid.MapActionViewEngine.csproj index 348afc5b..485695dc 100644 --- a/Fluid.MapActionViewEngine/Fluid.MapActionViewEngine.csproj +++ b/Fluid.MapActionViewEngine/Fluid.MapActionViewEngine.csproj @@ -5,6 +5,7 @@ 9 true logo_64x64.png + preview diff --git a/Fluid.MapActionViewEngine/LiquidResults.cs b/Fluid.MapActionViewEngine/LiquidResults.cs new file mode 100644 index 00000000..126b6bee --- /dev/null +++ b/Fluid.MapActionViewEngine/LiquidResults.cs @@ -0,0 +1,22 @@ +using Fluid.MapActionViewEngine; + +namespace Microsoft.AspNetCore.Http +{ + public static class LiquidResults + { + public static IResult View(string viewName) + { + return new ActionViewResult(viewName); + } + + public static IResult View(string viewName, object model) + { + return new ActionViewResult(viewName, model); + } + + public static IResult View(string viewName, string area, object model) + { + return new ActionViewResult(viewName, area, model); + } + } +} diff --git a/Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs b/Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs index 0f92af51..6b24c8f4 100644 --- a/Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs +++ b/Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs @@ -1,9 +1,8 @@ -using Fluid.ViewEngine; -using Microsoft.Extensions.DependencyInjection; +using Fluid.MapActionViewEngine; +using Fluid.ViewEngine; using Microsoft.Extensions.Options; -using System; -namespace Fluid.MapActionViewEngine +namespace Microsoft.Extensions.DependencyInjection { public static class MapActionViewEngineBuilderExtensions { @@ -29,7 +28,6 @@ public static IServiceCollection AddFluid(this IServiceCollection services, Acti }); return services; - } } } From c4d46ba911f76d02b514f8390a14b8a4321de293 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 18 Aug 2021 16:38:19 -0700 Subject: [PATCH 05/11] Pin dotnet 6 version --- .github/workflows/build.yml | 2 +- .github/workflows/publish.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 52709124..2566c63a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,7 @@ jobs: - name: Setup dotnet 6.0 uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.* + dotnet-version: 6.0.0-preview.7 - name: Test run: dotnet test --configuration Release diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e86f9c8c..774a84aa 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,7 +18,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.* + dotnet-version: 6.0.0-preview.7 - name: Install dependencies run: dotnet restore - name: Test From 325aaf2e544b271a83867687cc1b75c7394fc775 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 18 Aug 2021 16:39:48 -0700 Subject: [PATCH 06/11] Use SDK version number --- .github/workflows/build.yml | 2 +- .github/workflows/publish.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2566c63a..19c78b6d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,7 @@ jobs: - name: Setup dotnet 6.0 uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.0-preview.7 + dotnet-version: 6.0.100-preview.7 - name: Test run: dotnet test --configuration Release diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 774a84aa..958b0ec3 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,7 +18,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.0-preview.7 + dotnet-version: 6.0.100-preview.7 - name: Install dependencies run: dotnet restore - name: Test From 7d177f4adc72e67237b659d801797ff2b05acd83 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 18 Aug 2021 16:42:14 -0700 Subject: [PATCH 07/11] Use full version --- .github/workflows/build.yml | 2 +- .github/workflows/publish.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 19c78b6d..3969661e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,7 @@ jobs: - name: Setup dotnet 6.0 uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.100-preview.7 + dotnet-version: 6.0.100-preview.7.21379.14 - name: Test run: dotnet test --configuration Release diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 958b0ec3..4f9fbe2b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,7 +18,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.100-preview.7 + dotnet-version: 6.0.100-preview.7.21379.14 - name: Install dependencies run: dotnet restore - name: Test From f65ac3f5b38c5135e1019bc5b203ad5b8a506ac5 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Thu, 19 Aug 2021 09:10:25 -0700 Subject: [PATCH 08/11] Remove UseRouting --- Fluid.MapActionSample/Program.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Fluid.MapActionSample/Program.cs b/Fluid.MapActionSample/Program.cs index a16a122d..01185300 100644 --- a/Fluid.MapActionSample/Program.cs +++ b/Fluid.MapActionSample/Program.cs @@ -8,8 +8,6 @@ // Configure the HTTP request pipeline. -app.UseRouting(); - app.MapGet("/", () => { return LiquidResults.View("index", new Todo(1, "Go back to work!", false)); From a92d125362ffd4befff5faa81da599f0727b14bb Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 12 Oct 2021 15:04:59 -0700 Subject: [PATCH 09/11] Update MapAction --- .../Fluid.MapActionSample.csproj | 5 +-- Fluid.MapActionSample/Program.cs | 7 ++--- Fluid.MapActionSample/Views/_layout.liquid | 7 ++--- Fluid.MapActionSample/appsettings.json | 3 +- Fluid.MapActionViewEngine/ActionViewResult.cs | 31 +++++++++---------- .../FluidViewEngineOptionsSetup.cs | 16 +++++++--- Fluid.MapActionViewEngine/LiquidResults.cs | 11 ++----- .../MapActionViewEngineBuilderExtensions.cs | 1 + 8 files changed, 39 insertions(+), 42 deletions(-) diff --git a/Fluid.MapActionSample/Fluid.MapActionSample.csproj b/Fluid.MapActionSample/Fluid.MapActionSample.csproj index 69e0b504..66c8131a 100644 --- a/Fluid.MapActionSample/Fluid.MapActionSample.csproj +++ b/Fluid.MapActionSample/Fluid.MapActionSample.csproj @@ -1,8 +1,9 @@  - net6.0 - Exe + net6.0 + enable + Exe $(NoWarn);NU5104 false preview diff --git a/Fluid.MapActionSample/Program.cs b/Fluid.MapActionSample/Program.cs index 01185300..74a84388 100644 --- a/Fluid.MapActionSample/Program.cs +++ b/Fluid.MapActionSample/Program.cs @@ -8,11 +8,8 @@ // Configure the HTTP request pipeline. -app.MapGet("/", () => -{ - return LiquidResults.View("index", new Todo(1, "Go back to work!", false)); -}); +app.MapGet("/", () => Results.Extensions.View("Index", new Todo(1, "Go back to work!", false))); -app.Run(); +await app.RunAsync(); record Todo(int Id, string Name, bool IsComplete); diff --git a/Fluid.MapActionSample/Views/_layout.liquid b/Fluid.MapActionSample/Views/_layout.liquid index 49c548fe..fd07b1b8 100644 --- a/Fluid.MapActionSample/Views/_layout.liquid +++ b/Fluid.MapActionSample/Views/_layout.liquid @@ -1,4 +1,3 @@ - @@ -17,11 +16,11 @@

Title from the layout

- {% renderbody %} + {% renderbody %} - {% include 'component', x: 1, y:2 %} + {% partial 'Component', x: 1, y:2 %} -

+

diff --git a/Fluid.MapActionSample/appsettings.json b/Fluid.MapActionSample/appsettings.json index c9294ca4..b0bacf42 100644 --- a/Fluid.MapActionSample/appsettings.json +++ b/Fluid.MapActionSample/appsettings.json @@ -2,8 +2,7 @@ "Logging": { "LogLevel": { "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" + "Microsoft.AspNetCore": "Warning" } } } diff --git a/Fluid.MapActionViewEngine/ActionViewResult.cs b/Fluid.MapActionViewEngine/ActionViewResult.cs index 4c7eb71d..45db7121 100644 --- a/Fluid.MapActionViewEngine/ActionViewResult.cs +++ b/Fluid.MapActionViewEngine/ActionViewResult.cs @@ -2,13 +2,15 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using System; +using System.IO; +using System.Threading.Tasks; namespace Fluid.MapActionViewEngine { public class ActionViewResult : IResult { private readonly string _viewName; - private readonly string _area; private readonly object _model; public ActionViewResult(string viewName) @@ -23,13 +25,6 @@ public ActionViewResult(string viewName, object model) _model = model; } - public ActionViewResult(string viewName, string area, object model) - { - _viewName = viewName; - _area = area; - _model = model; - } - public string ContentType { get; set; } = "text/html"; public async Task ExecuteAsync(HttpContext httpContext) @@ -37,7 +32,7 @@ public async Task ExecuteAsync(HttpContext httpContext) var fluidViewRenderer = httpContext.RequestServices.GetService(); var options = httpContext.RequestServices.GetService>().Value; - var viewPath = LocatePageFromViewLocations(_viewName, _area, options); + var viewPath = LocatePageFromViewLocations(_viewName, options); if (viewPath == null) { @@ -48,22 +43,26 @@ public async Task ExecuteAsync(HttpContext httpContext) httpContext.Response.StatusCode = 200; httpContext.Response.ContentType = ContentType; + var context = new TemplateContext(_model); + context.Options.FileProvider = options.PartialsFileProvider; + await using var sw = new StreamWriter(httpContext.Response.Body); - await fluidViewRenderer.RenderViewAsync(sw, viewPath, _model); + await fluidViewRenderer.RenderViewAsync(sw, viewPath, context); } - private static string LocatePageFromViewLocations(string viewName, string area, FluidViewEngineOptions options) + private static string LocatePageFromViewLocations(string viewName, FluidViewEngineOptions options) { var fileProvider = options.ViewsFileProvider; - foreach (var location in options.ViewLocationFormats) + foreach (var location in options.ViewsLocationFormats) { - var viewPath = string.Format(location, viewName, area); - var fileInfo = fileProvider.GetFileInfo(viewPath); - + var viewFilename = Path.Combine(String.Format(location, viewName)); + + var fileInfo = fileProvider.GetFileInfo(viewFilename); + if (fileInfo.Exists) { - return viewPath; + return viewFilename; } } diff --git a/Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs b/Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs index 7bb64368..3c3b3939 100644 --- a/Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs +++ b/Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs @@ -9,12 +9,18 @@ public class FluidViewEngineOptionsSetup : ConfigureOptions { - options.IncludesFileProvider = webHostEnvironment.ContentRootFileProvider; - options.ViewsFileProvider = webHostEnvironment.ContentRootFileProvider; - options.ViewLocationFormats.Add("Views/{0}" + Constants.ViewExtension); - options.ViewLocationFormats.Add("Views/{1}/{0}" + Constants.ViewExtension); - options.ViewLocationFormats.Add("Views/Shared/{0}" + Constants.ViewExtension); + options.PartialsFileProvider = new FileProviderMapper(webHostEnvironment.ContentRootFileProvider, "Views"); + options.ViewsFileProvider = new FileProviderMapper(webHostEnvironment.ContentRootFileProvider, "Views"); + options.TemplateOptions.MemberAccessStrategy = UnsafeMemberAccessStrategy.Instance; + + options.ViewsLocationFormats.Clear(); + options.ViewsLocationFormats.Add("/{0}" + Constants.ViewExtension); + + options.PartialsLocationFormats.Clear(); + options.PartialsLocationFormats.Add("{0}" + Constants.ViewExtension); + options.PartialsLocationFormats.Add("/Partials/{0}" + Constants.ViewExtension); + }) { } diff --git a/Fluid.MapActionViewEngine/LiquidResults.cs b/Fluid.MapActionViewEngine/LiquidResults.cs index 126b6bee..52cefd32 100644 --- a/Fluid.MapActionViewEngine/LiquidResults.cs +++ b/Fluid.MapActionViewEngine/LiquidResults.cs @@ -2,21 +2,16 @@ namespace Microsoft.AspNetCore.Http { - public static class LiquidResults + public static class ResultExtensions { - public static IResult View(string viewName) + public static IResult View(this IResultExtensions result, string viewName) { return new ActionViewResult(viewName); } - public static IResult View(string viewName, object model) + public static IResult View(this IResultExtensions result, string viewName, object model) { return new ActionViewResult(viewName, model); } - - public static IResult View(string viewName, string area, object model) - { - return new ActionViewResult(viewName, area, model); - } } } diff --git a/Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs b/Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs index 6b24c8f4..0356780a 100644 --- a/Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs +++ b/Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs @@ -1,6 +1,7 @@ using Fluid.MapActionViewEngine; using Fluid.ViewEngine; using Microsoft.Extensions.Options; +using System; namespace Microsoft.Extensions.DependencyInjection { From 170318cd22e675ef67c53807bca922a56af7ae44 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 12 Oct 2021 15:34:49 -0700 Subject: [PATCH 10/11] Update dotnet 6 version --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3969661e..6748cba9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,7 @@ jobs: - name: Setup dotnet 6.0 uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.100-preview.7.21379.14 + dotnet-version: 6.0.100-rc.2.21505.57 - name: Test run: dotnet test --configuration Release From 079dabdfca622f64e07bd89225fd2a1a034669bd Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Fri, 19 Nov 2021 19:16:31 -0800 Subject: [PATCH 11/11] Prepare package --- .github/workflows/build.yml | 11 +- .github/workflows/publish.yml | 3 +- Common.props | 10 +- .../Fluid.MinimalApisSample.csproj | 2 +- .../Program.cs | 0 Fluid.MinimalApisSample/README.md | 101 ++++++++++++++++++ .../Views/_layout.liquid | 0 .../Views/_viewstart.liquid | 0 .../Views/component.liquid | 0 .../Views/index.liquid | 0 .../appsettings.json | 0 Fluid.MvcViewEngine/MvcViewOptionsSetup.cs | 2 +- Fluid.sln | 26 ++--- Fluid/Fluid.csproj | 8 +- .../ActionViewResult.cs | 5 +- .../Directory.Build.props | 0 .../FluidViewEngineOptionsSetup.cs | 5 +- .../LiquidResults.cs | 2 +- .../MapActionViewEngineBuilderExtensions.cs | 4 +- .../MinimalApis.LiquidViews.csproj | 9 +- MinimalApis.LiquidViews/README.md | 97 +++++++++++++++++ 21 files changed, 252 insertions(+), 33 deletions(-) rename Fluid.MapActionSample/Fluid.MapActionSample.csproj => Fluid.MinimalApisSample/Fluid.MinimalApisSample.csproj (78%) rename {Fluid.MapActionSample => Fluid.MinimalApisSample}/Program.cs (100%) create mode 100644 Fluid.MinimalApisSample/README.md rename {Fluid.MapActionSample => Fluid.MinimalApisSample}/Views/_layout.liquid (100%) rename {Fluid.MapActionSample => Fluid.MinimalApisSample}/Views/_viewstart.liquid (100%) rename {Fluid.MapActionSample => Fluid.MinimalApisSample}/Views/component.liquid (100%) rename {Fluid.MapActionSample => Fluid.MinimalApisSample}/Views/index.liquid (100%) rename {Fluid.MapActionSample => Fluid.MinimalApisSample}/appsettings.json (100%) rename {Fluid.MapActionViewEngine => MinimalApis.LiquidViews}/ActionViewResult.cs (96%) rename {Fluid.MapActionViewEngine => MinimalApis.LiquidViews}/Directory.Build.props (100%) rename {Fluid.MapActionViewEngine => MinimalApis.LiquidViews}/FluidViewEngineOptionsSetup.cs (93%) rename {Fluid.MapActionViewEngine => MinimalApis.LiquidViews}/LiquidResults.cs (92%) rename {Fluid.MapActionViewEngine => MinimalApis.LiquidViews}/MapActionViewEngineBuilderExtensions.cs (94%) rename Fluid.MapActionViewEngine/Fluid.MapActionViewEngine.csproj => MinimalApis.LiquidViews/MinimalApis.LiquidViews.csproj (77%) create mode 100644 MinimalApis.LiquidViews/README.md diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 186a6bed..327bb239 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,23 +23,22 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Setup dotnet 2.1 + - name: Setup .NET 2.1 uses: actions/setup-dotnet@v1 with: dotnet-version: 2.1.* - - name: Setup dotnet 3.1 + - name: Setup .NET 3.1 uses: actions/setup-dotnet@v1 with: dotnet-version: 3.1.* - - name: Setup dotnet 5.0 + - name: Setup .NET 5.0 uses: actions/setup-dotnet@v1 with: dotnet-version: 5.0.* - - name: Setup dotnet 6.0 + - name: Setup .NET 6.0 uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.x - include-prerelease: true + dotnet-version: 6.0.* - name: Test run: dotnet test --configuration Release - name: Test - Compiled diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 194f8950..303f9e16 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,8 +18,7 @@ jobs: - name: Setup dotnet 6.0 uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.x - include-prerelease: true + dotnet-version: 6.0.* - name: Install dependencies run: dotnet restore - name: Test diff --git a/Common.props b/Common.props index 33cf039f..9ec1bcd5 100644 --- a/Common.props +++ b/Common.props @@ -12,7 +12,15 @@ true true snupkg - portable + true + true + latest + $(NoWarn);1591 + + + true + true + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb true false diff --git a/Fluid.MapActionSample/Fluid.MapActionSample.csproj b/Fluid.MinimalApisSample/Fluid.MinimalApisSample.csproj similarity index 78% rename from Fluid.MapActionSample/Fluid.MapActionSample.csproj rename to Fluid.MinimalApisSample/Fluid.MinimalApisSample.csproj index 66c8131a..6c5f0dfb 100644 --- a/Fluid.MapActionSample/Fluid.MapActionSample.csproj +++ b/Fluid.MinimalApisSample/Fluid.MinimalApisSample.csproj @@ -10,7 +10,7 @@
- +
diff --git a/Fluid.MapActionSample/Program.cs b/Fluid.MinimalApisSample/Program.cs similarity index 100% rename from Fluid.MapActionSample/Program.cs rename to Fluid.MinimalApisSample/Program.cs diff --git a/Fluid.MinimalApisSample/README.md b/Fluid.MinimalApisSample/README.md new file mode 100644 index 00000000..5a15c048 --- /dev/null +++ b/Fluid.MinimalApisSample/README.md @@ -0,0 +1,101 @@ +## MinimalApis.LiquidViews + +This library provides some extensions to ASP.NET Minimal APIs that allow to return templated view results using the Liquid language. +Liquid is fast and safe. Views are interpreted so changes are reflected very quickly without a compilation phase. + +This View Engine is based on [Fluid](https://github.com/sebastienros/fluid), a Liquid template engine for .NET. + +## Sample usage + +These files demonstrates how to return a view result, which will be able to use +- a `_layout` file to act as a template for multiple pages +- a `_viewstart` file to be executed for each view +- a `component` file to act like partial views + +The full sample can be found [here](https://github.com/sebastienros/fluid/tree/main/Fluid.MinimalApisSample) + +#### Program.cs + +```c# +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddFluid(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. + +app.MapGet("/", () => Results.Extensions.View("Index", new Todo(1, "Go back to work!", false))); + +await app.RunAsync(); + +record Todo(int Id, string Name, bool IsComplete); +``` + +#### index.liquid + +```liquid +
+Hello World from the body + +Name: {{ Name }}
+IsComplete: {{ IsComplete}} +
+ +{% section footer %} +Hello from the footer section +{% endsection %} +``` + +#### _viewstart.liquid + +```liquid +{% layout '_Layout' %} +From /Views/_ViewStart.liquid +``` + +#### component.liquid + +```liquid +
Using a component {{ x }} + {{ y }} = {{ x | plus: y }}
+``` + +#### _layout.liquid + +```liquid + + + + + + + + + + + Hello, world! + + + +
+

Title from the layout

+
+

+ {% renderbody %} + + {% partial 'Component', x: 1, y:2 %} + +

+
+
+ +
+	{% rendersection footer %}
+	
+ + + + +``` \ No newline at end of file diff --git a/Fluid.MapActionSample/Views/_layout.liquid b/Fluid.MinimalApisSample/Views/_layout.liquid similarity index 100% rename from Fluid.MapActionSample/Views/_layout.liquid rename to Fluid.MinimalApisSample/Views/_layout.liquid diff --git a/Fluid.MapActionSample/Views/_viewstart.liquid b/Fluid.MinimalApisSample/Views/_viewstart.liquid similarity index 100% rename from Fluid.MapActionSample/Views/_viewstart.liquid rename to Fluid.MinimalApisSample/Views/_viewstart.liquid diff --git a/Fluid.MapActionSample/Views/component.liquid b/Fluid.MinimalApisSample/Views/component.liquid similarity index 100% rename from Fluid.MapActionSample/Views/component.liquid rename to Fluid.MinimalApisSample/Views/component.liquid diff --git a/Fluid.MapActionSample/Views/index.liquid b/Fluid.MinimalApisSample/Views/index.liquid similarity index 100% rename from Fluid.MapActionSample/Views/index.liquid rename to Fluid.MinimalApisSample/Views/index.liquid diff --git a/Fluid.MapActionSample/appsettings.json b/Fluid.MinimalApisSample/appsettings.json similarity index 100% rename from Fluid.MapActionSample/appsettings.json rename to Fluid.MinimalApisSample/appsettings.json diff --git a/Fluid.MvcViewEngine/MvcViewOptionsSetup.cs b/Fluid.MvcViewEngine/MvcViewOptionsSetup.cs index 866414e4..02bcf12f 100644 --- a/Fluid.MvcViewEngine/MvcViewOptionsSetup.cs +++ b/Fluid.MvcViewEngine/MvcViewOptionsSetup.cs @@ -11,7 +11,7 @@ internal class MvcViewOptionsSetup : IConfigureOptions private readonly IFluidViewEngine _fluidViewEngine; /// - /// Initializes a new instance of . + /// Initializes a new instance of . /// /// The . public MvcViewOptionsSetup(IFluidViewEngine fluidViewEngine) diff --git a/Fluid.sln b/Fluid.sln index 0ccf7f45..0bed0a11 100644 --- a/Fluid.sln +++ b/Fluid.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.28606.126 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.31903.286 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fluid", "Fluid\Fluid.csproj", "{8CD687F1-AC65-4E4A-A510-67768999C81C}" EndProject @@ -23,11 +23,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Files", "Files", "{BE5EF08E README.md = README.md EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fluid.ViewEngine", "Fluid.ViewEngine\Fluid.ViewEngine.csproj", "{3510D4C5-8328-4425-B2F1-B8591E85B965}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fluid.ViewEngine", "Fluid.ViewEngine\Fluid.ViewEngine.csproj", "{3510D4C5-8328-4425-B2F1-B8591E85B965}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fluid.MapActionSample", "Fluid.MapActionSample\Fluid.MapActionSample.csproj", "{03BE4428-3251-4115-93E4-C488E4249FB3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MinimalApis.LiquidViews", "MinimalApis.LiquidViews\MinimalApis.LiquidViews.csproj", "{DD0B5036-D5E6-4E6E-8405-27F6C2FD5917}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fluid.MapActionViewEngine", "Fluid.MapActionViewEngine\Fluid.MapActionViewEngine.csproj", "{0ACE7D6B-AC02-48D5-875F-56B576A0DE54}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Fluid.MinimalApisSample", "Fluid.MinimalApisSample\Fluid.MinimalApisSample.csproj", "{6390F2D4-564B-455E-9C02-3DB998E5BD09}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -59,14 +59,14 @@ Global {3510D4C5-8328-4425-B2F1-B8591E85B965}.Debug|Any CPU.Build.0 = Debug|Any CPU {3510D4C5-8328-4425-B2F1-B8591E85B965}.Release|Any CPU.ActiveCfg = Release|Any CPU {3510D4C5-8328-4425-B2F1-B8591E85B965}.Release|Any CPU.Build.0 = Release|Any CPU - {03BE4428-3251-4115-93E4-C488E4249FB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {03BE4428-3251-4115-93E4-C488E4249FB3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {03BE4428-3251-4115-93E4-C488E4249FB3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {03BE4428-3251-4115-93E4-C488E4249FB3}.Release|Any CPU.Build.0 = Release|Any CPU - {0ACE7D6B-AC02-48D5-875F-56B576A0DE54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0ACE7D6B-AC02-48D5-875F-56B576A0DE54}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0ACE7D6B-AC02-48D5-875F-56B576A0DE54}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0ACE7D6B-AC02-48D5-875F-56B576A0DE54}.Release|Any CPU.Build.0 = Release|Any CPU + {DD0B5036-D5E6-4E6E-8405-27F6C2FD5917}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DD0B5036-D5E6-4E6E-8405-27F6C2FD5917}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DD0B5036-D5E6-4E6E-8405-27F6C2FD5917}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DD0B5036-D5E6-4E6E-8405-27F6C2FD5917}.Release|Any CPU.Build.0 = Release|Any CPU + {6390F2D4-564B-455E-9C02-3DB998E5BD09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6390F2D4-564B-455E-9C02-3DB998E5BD09}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6390F2D4-564B-455E-9C02-3DB998E5BD09}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6390F2D4-564B-455E-9C02-3DB998E5BD09}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Fluid/Fluid.csproj b/Fluid/Fluid.csproj index 0013e6c7..9ae537b1 100644 --- a/Fluid/Fluid.csproj +++ b/Fluid/Fluid.csproj @@ -13,7 +13,7 @@ - +
@@ -36,4 +36,10 @@ + + README.md + + + + diff --git a/Fluid.MapActionViewEngine/ActionViewResult.cs b/MinimalApis.LiquidViews/ActionViewResult.cs similarity index 96% rename from Fluid.MapActionViewEngine/ActionViewResult.cs rename to MinimalApis.LiquidViews/ActionViewResult.cs index 45db7121..ce0d83af 100644 --- a/Fluid.MapActionViewEngine/ActionViewResult.cs +++ b/MinimalApis.LiquidViews/ActionViewResult.cs @@ -1,4 +1,5 @@ -using Fluid.ViewEngine; +using Fluid; +using Fluid.ViewEngine; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -6,7 +7,7 @@ using System.IO; using System.Threading.Tasks; -namespace Fluid.MapActionViewEngine +namespace MinimalApis.LiquidViews { public class ActionViewResult : IResult { diff --git a/Fluid.MapActionViewEngine/Directory.Build.props b/MinimalApis.LiquidViews/Directory.Build.props similarity index 100% rename from Fluid.MapActionViewEngine/Directory.Build.props rename to MinimalApis.LiquidViews/Directory.Build.props diff --git a/Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs b/MinimalApis.LiquidViews/FluidViewEngineOptionsSetup.cs similarity index 93% rename from Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs rename to MinimalApis.LiquidViews/FluidViewEngineOptionsSetup.cs index 3c3b3939..2b4ba234 100644 --- a/Fluid.MapActionViewEngine/FluidViewEngineOptionsSetup.cs +++ b/MinimalApis.LiquidViews/FluidViewEngineOptionsSetup.cs @@ -1,8 +1,9 @@ -using Fluid.ViewEngine; +using Fluid; +using Fluid.ViewEngine; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Options; -namespace Fluid.MapActionViewEngine +namespace MinimalApis.LiquidViews { public class FluidViewEngineOptionsSetup : ConfigureOptions { diff --git a/Fluid.MapActionViewEngine/LiquidResults.cs b/MinimalApis.LiquidViews/LiquidResults.cs similarity index 92% rename from Fluid.MapActionViewEngine/LiquidResults.cs rename to MinimalApis.LiquidViews/LiquidResults.cs index 52cefd32..ac3d3e16 100644 --- a/Fluid.MapActionViewEngine/LiquidResults.cs +++ b/MinimalApis.LiquidViews/LiquidResults.cs @@ -1,4 +1,4 @@ -using Fluid.MapActionViewEngine; +using MinimalApis.LiquidViews; namespace Microsoft.AspNetCore.Http { diff --git a/Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs b/MinimalApis.LiquidViews/MapActionViewEngineBuilderExtensions.cs similarity index 94% rename from Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs rename to MinimalApis.LiquidViews/MapActionViewEngineBuilderExtensions.cs index 0356780a..bfff7e01 100644 --- a/Fluid.MapActionViewEngine/MapActionViewEngineBuilderExtensions.cs +++ b/MinimalApis.LiquidViews/MapActionViewEngineBuilderExtensions.cs @@ -1,6 +1,6 @@ -using Fluid.MapActionViewEngine; -using Fluid.ViewEngine; +using Fluid.ViewEngine; using Microsoft.Extensions.Options; +using MinimalApis.LiquidViews; using System; namespace Microsoft.Extensions.DependencyInjection diff --git a/Fluid.MapActionViewEngine/Fluid.MapActionViewEngine.csproj b/MinimalApis.LiquidViews/MinimalApis.LiquidViews.csproj similarity index 77% rename from Fluid.MapActionViewEngine/Fluid.MapActionViewEngine.csproj rename to MinimalApis.LiquidViews/MinimalApis.LiquidViews.csproj index 485695dc..bf328919 100644 --- a/Fluid.MapActionViewEngine/Fluid.MapActionViewEngine.csproj +++ b/MinimalApis.LiquidViews/MinimalApis.LiquidViews.csproj @@ -5,7 +5,6 @@ 9 true logo_64x64.png - preview @@ -19,4 +18,12 @@ + + + README.md + + + + + diff --git a/MinimalApis.LiquidViews/README.md b/MinimalApis.LiquidViews/README.md new file mode 100644 index 00000000..ab9a0039 --- /dev/null +++ b/MinimalApis.LiquidViews/README.md @@ -0,0 +1,97 @@ +## MinimalApis.LiquidViews + +This library provides some extensions to ASP.NET Minimal APIs that allow to return templated view results using the Liquid language. +Liquid is fast and safe. Views are interpreted so changes are reflected very quickly without a compilation phase. + +## Sample usage + +These files demonstrates how to return a view result, which will be able to use +- a `_layout` file to act as a template for multiple pages +- a `_viewstart` file to be executed for each view +- a `component` file to act like partial views + +#### Program.cs + +```c# +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddFluid(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. + +app.MapGet("/", () => Results.Extensions.View("Index", new Todo(1, "Go back to work!", false))); + +await app.RunAsync(); + +record Todo(int Id, string Name, bool IsComplete); +``` + +#### index.liquid + +```liquid +
+Hello World from the body + +Name: {{ Name }}
+IsComplete: {{ IsComplete}} +
+ +{% section footer %} +Hello from the footer section +{% endsection %} +``` + +#### _viewstart.liquid + +```liquid +{% layout '_Layout' %} +From /Views/_ViewStart.liquid +``` + +#### component.liquid + +```liquid +
Using a component {{ x }} + {{ y }} = {{ x | plus: y }}
+``` + +#### _layout.liquid + +```liquid + + + + + + + + + + + Hello, world! + + + +
+

Title from the layout

+
+

+ {% renderbody %} + + {% partial 'Component', x: 1, y:2 %} + +

+
+
+ +
+	{% rendersection footer %}
+	
+ + + + +``` \ No newline at end of file