45 lines
1.6 KiB
C#
45 lines
1.6 KiB
C#
using Microsoft.AspNetCore.Antiforgery;
|
|
|
|
namespace Htmx.ApiDemo;
|
|
|
|
/// <summary>
|
|
/// Renders a full page or just the body component depending on whether
|
|
/// the request was made by HTMX (HX-Request header present).
|
|
///
|
|
/// Full request → wraps body in MainLayout (complete HTML page)
|
|
/// HTMX request → renders body only + sets HX-Title so the browser
|
|
/// tab title still updates
|
|
/// </summary>
|
|
public static class HtmxPageExtensions
|
|
{
|
|
public static void WriteHtmxPage(
|
|
this HttpContext ctx,
|
|
IHtmxComponent body,
|
|
string title = "App",
|
|
string appName = "HtmxApp",
|
|
string pageTitle = "")
|
|
{
|
|
if (ctx.Request.Headers.ContainsKey("HX-Request"))
|
|
{
|
|
// Partial swap: tell HTMX to update the browser <title> tag
|
|
ctx.Response.Headers["HX-Title"] = title;
|
|
ctx.WriteHtmxBody(body);
|
|
}
|
|
else
|
|
{
|
|
// Resolve display name: prefer DisplayName claim, fall back to email/name
|
|
string? userName = ctx.User.Identity?.IsAuthenticated == true
|
|
? (ctx.User.FindFirst("DisplayName")?.Value
|
|
?? ctx.User.FindFirst(System.Security.Claims.ClaimTypes.Name)?.Value)
|
|
: null;
|
|
|
|
// Resolve antiforgery token for the logout form in the layout
|
|
var antiforgery = ctx.RequestServices.GetRequiredService<IAntiforgery>();
|
|
var afTokens = antiforgery.GetAndStoreTokens(ctx);
|
|
|
|
// Full page load: wrap in the shell layout
|
|
ctx.WriteHtmxBody(new Templates.MainLayout(body, title, appName, pageTitle, userName, afTokens.RequestToken));
|
|
}
|
|
}
|
|
}
|