Fable clean up

This commit is contained in:
Andras Schmelczer 2026-06-11 21:35:45 +01:00
parent 3441a7e4af
commit 4ce8a4f41d
46 changed files with 642 additions and 911 deletions

View file

@ -3,6 +3,12 @@ import { getCollection } from 'astro:content';
import { getImage } from 'astro:assets';
import type { ImageMetadata } from 'astro';
// Theme background colors, the single source of truth for the
// <meta name="theme-color"> tags and the FOUC-prevention scripts (injected in
// Base.astro and Header.astro). Keep --color-bg in global.css in sync; CSS
// cannot import these values.
export const THEME_BG = { light: '#fbfaf7', dark: '#201f1d' };
export const site = {
brand: 'schmelczer.dev',
name: 'Andras Schmelczer',
@ -54,6 +60,17 @@ export function yearOf(date: Date) {
return new Intl.DateTimeFormat('en', { year: 'numeric' }).format(date);
}
export function isExternal(url: string) {
return /^https?:\/\//.test(url);
}
// Directory-style paths get a trailing slash; the root and file-style paths
// (e.g. /rss.xml) pass through unchanged. Shared by canonical URL generation
// and the header's current-page matching so the two can never disagree.
export function normalizeTrailingSlash(path: string) {
return path === '/' || path.endsWith('/') || /\.[^/]+$/.test(path) ? path : `${path}/`;
}
export function entrySlug(entry: { id: string }) {
return entry.id.replace(/\.mdx?$/, '').replace(/\/index$/, '');
}
@ -268,6 +285,15 @@ export function buildBreadcrumbTrail({
return trail;
}
// Adapts a trail for the visible Breadcrumbs component, which renders the
// current page (the last crumb) as plain text rather than a link.
export function visibleBreadcrumbs(trail: BreadcrumbCrumb[]) {
return trail.map((crumb, index) => ({
label: crumb.name,
href: index === trail.length - 1 ? undefined : crumb.href,
}));
}
// Builds the schema.org BreadcrumbList JSON-LD object for a given trail.
// Shared by every page that emits breadcrumb structured data.
export function buildBreadcrumbJsonLd(trail: BreadcrumbCrumb[]) {