diff --git a/Elternbeirat.Contracts/Page.cs b/Elternbeirat.Contracts/Page.cs index 5bfa2fb..7204d72 100644 --- a/Elternbeirat.Contracts/Page.cs +++ b/Elternbeirat.Contracts/Page.cs @@ -13,6 +13,12 @@ namespace Elternbeirat.Contracts; /// public record Page { + /// + /// The slug of the home page, which is served at the site root / rather + /// than at /home. Reserved: no other page may use it. + /// + private const string HomeSlug = "home"; + /// /// Gets the PocketBase record id. /// @@ -76,4 +82,18 @@ public record Page /// [JsonPropertyName("public")] public bool Public { get; init; } + + /// + /// Tests whether a slug is the home page's, ignoring case. This is the single + /// definition of that comparison, so every caller treats home and + /// Home alike. + /// + /// + /// The slug to test. + /// + /// + /// if is the home page's slug. + /// + public static bool IsHomeSlug(string slug) => + string.Equals(slug, HomeSlug, StringComparison.OrdinalIgnoreCase); } diff --git a/Elternbeirat.Web/Features/Home/Home.razor.cs b/Elternbeirat.Web/Features/Home/Home.razor.cs index e5739c1..6753823 100644 --- a/Elternbeirat.Web/Features/Home/Home.razor.cs +++ b/Elternbeirat.Web/Features/Home/Home.razor.cs @@ -1,3 +1,4 @@ +using Elternbeirat.Contracts; using Elternbeirat.PocketBase; using Microsoft.AspNetCore.Components; @@ -5,14 +6,18 @@ namespace Elternbeirat.Web.Features.Home; public partial class Home { - [LoggerMessage(Level = LogLevel.Warning, Message = "Could not load the home page from PocketBase.")] - private static partial void LogLoadFailed(ILogger logger, Exception exception); + [LoggerMessage( + Level = LogLevel.Warning, + Message = "Could not load the home page from PocketBase.")] + private static partial void LogLoadFailed( + ILogger logger, + Exception exception); [Inject] - private PocketBaseClient PocketBase { get; set; } = default!; + private PocketBaseClient PocketBase { get; set; } = null!; [Inject] - private ILogger Logger { get; set; } = default!; + private ILogger Logger { get; set; } = null!; // Which dynamic blocks the home page shows is editorial: it comes from the // "home" page's embed field in PocketBase, not from hard-coded markup. @@ -23,14 +28,13 @@ public partial class Home try { var pages = await PocketBase.GetPagesAsync(); - var home = pages.FirstOrDefault( - p => string.Equals(p.Slug, "home", StringComparison.Ordinal)); + var home = pages.FirstOrDefault(page => Page.IsHomeSlug(page.Slug)); _embed = home?.Embed ?? []; } - catch (HttpRequestException ex) + catch (HttpRequestException exception) { // Source unreachable -> render the intro without embeds instead of a 500. - LogLoadFailed(Logger, ex); + LogLoadFailed(Logger, exception); } } } diff --git a/Elternbeirat.Web/Features/Layout/NavBuilder.cs b/Elternbeirat.Web/Features/Layout/NavBuilder.cs index 0e82666..c1f9df0 100644 --- a/Elternbeirat.Web/Features/Layout/NavBuilder.cs +++ b/Elternbeirat.Web/Features/Layout/NavBuilder.cs @@ -17,7 +17,9 @@ public static class NavBuilder public static IReadOnlyList Footer(IReadOnlyList pages) => Build(pages, "footer"); - private static List Build(IReadOnlyList pages, string location) => + private static List Build( + IReadOnlyList pages, + string location) => [.. pages .Where(page => string.Equals(page.Location, location, StringComparison.Ordinal)) .OrderBy(page => page.Order) @@ -27,5 +29,5 @@ public static class NavBuilder // reached at "/{slug}", where either a literal route or the catch-all content // page renders it. private static string HrefFor(string slug) => - string.Equals(slug, "home", StringComparison.Ordinal) ? "/" : $"/{slug}"; + Page.IsHomeSlug(slug) ? "/" : $"/{slug}"; }