posts and avif
Some checks failed
Deploy / build-deploy (push) Failing after 5m49s

This commit is contained in:
Jorijn van der Graaf 2026-08-10 01:37:26 +02:00
commit 6841623e23
17 changed files with 2306 additions and 148 deletions

View file

@ -23,6 +23,7 @@ export enum class RouteKind {
About, // /about — the person behind the company
Projects,
Posts,
Post, // /posts/<slug> — one post, in full
Demos, // /demos — the list
Demo, // /demos/<slug>
Shop, // /shop — the (currently single-item) product list
@ -45,7 +46,8 @@ export struct Route {
std::string query; // raw, including leading '?', or empty
// Non-empty when the request should be canonicalised to a different URL.
std::string canonicalRedirect;
// The <slug> of /shop/<slug>, empty for every other route.
// The <slug> of /shop/<slug>, /demos/<slug>, /legal/<slug> or /posts/<slug>
// (and the token of /order/<token>); empty for every other route.
std::string slug;
};
@ -134,6 +136,20 @@ export Route ParseRoute(std::string_view path, std::string_view query = {}) {
return r;
}
// /posts/<slug>. Whether a slug names a post the site actually has is the
// dispatcher's question, exactly as it is for /shop/<slug>; this only
// decides that the URL is shaped like a post page at all.
if (p.starts_with("/posts/")) {
const std::string_view slug = p.substr(7);
if (IsValidSlug(slug)) {
r.kind = RouteKind::Post;
r.slug = std::string(slug);
return r;
}
r.kind = RouteKind::NotFound;
return r;
}
if (p.starts_with("/demos/")) {
const std::string_view slug = p.substr(7);
if (IsValidSlug(slug)) {
@ -183,6 +199,20 @@ export struct NavItem {
RouteKind kind;
};
// Which nav entry a route highlights. A route that is not itself a nav entry
// borrows its section's: an individual post and the retired /blog URL both sit
// under Posts. Shared so the three call sites (the server, the CLI renderer and
// the wasm router) cannot disagree about where the reader is — they each used
// to spell the /blog case out, and the third one to be added would have been
// the third chance to forget it.
export RouteKind NavKindFor(RouteKind kind) {
switch (kind) {
case RouteKind::Post:
case RouteKind::LegacyBlog: return RouteKind::Posts;
default: return kind;
}
}
export std::span<const NavItem> NavItems() {
static constexpr std::array<NavItem, 6> items{{
{ "Home", "/", RouteKind::Home },