my website at ewancroft.uk
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

Normalise slugs, extract slug mappings to data module, add cspell entry

- Add normaliseSlug utility with JSDoc examples to ensure slugs are
URI-compatible (lowercase, spaces → hyphens, remove invalid chars,
collapse hyphens, trim).
- Move SlugMapping type and slugMappings array into a new
src/lib/data/slug-mappings.ts file to separate data from logic.
- Update src/lib/config/slugs.ts:
- import slugMappings and SlugMapping type from the new data module
- normalise slugs automatically before lookups (getPublicationRkeyFromSlug,
getAllSlugs) and normalise comparisons to make lookups more robust.
- add getAllSlugMappings() helper to return mappings with normalised slugs.
- improve comments and examples.
- Update .cspell.json to include "cailean".

This improves slug handling (more tolerant of casing, spacing, and special
characters), clarifies separation of concerns by extracting mapping data,
and adds a missing spelling entry.

+91 -33
+1
.cspell.json
··· 17 17 "bradlc", 18 18 "bsky", 19 19 "Caddyfile", 20 + "cailean", 20 21 "Caligraphic", 21 22 "CASL", 22 23 "Centralised",
+49 -33
src/lib/config/slugs.ts
··· 1 + import { slugMappings, type SlugMapping } from '$lib/data/slug-mappings'; 2 + 1 3 /** 2 - * Slug to Leaflet Publication mapping configuration 4 + * Normalize a slug to be URI-compatible 5 + * 6 + * Transformations: 7 + * - Convert to lowercase 8 + * - Replace spaces with hyphens 9 + * - Remove all characters except alphanumeric, hyphens, and underscores 10 + * - Collapse multiple hyphens into single hyphen 11 + * - Remove leading/trailing hyphens 3 12 * 4 - * Maps friendly URL slugs to Leaflet publication rkeys. 5 - * This allows you to access publications via /{slug} instead of /blog 13 + * @param slug - The slug to normalize 14 + * @returns URI-compatible slug 6 15 * 7 - * Example: 8 - * - /blog → maps to publication with rkey "3m3x4bgbsh22k" 9 - * - /notes → maps to publication with rkey "xyz123abc" 16 + * @example 17 + * normalizeSlug('My Blog Post!') // 'my-blog-post' 18 + * normalizeSlug('Hello World') // 'hello-world' 19 + * normalizeSlug('Test---Slug___') // 'test-slug' 10 20 */ 11 - 12 - export interface SlugMapping { 13 - /** The URL-friendly slug */ 14 - slug: string; 15 - /** The Leaflet publication rkey */ 16 - publicationRkey: string; 21 + export function normalizeSlug(slug: string): string { 22 + return slug 23 + .toLowerCase() 24 + .trim() 25 + .replace(/\s+/g, '-') // Replace spaces with hyphens 26 + .replace(/[^a-z0-9\-_]/g, '') // Remove non-alphanumeric except hyphens and underscores 27 + .replace(/-+/g, '-') // Collapse multiple hyphens 28 + .replace(/^-+|-+$/g, ''); // Remove leading/trailing hyphens 17 29 } 18 30 19 31 /** 20 - * Slug to publication rkey mappings 21 - * Add your custom mappings here 22 - */ 23 - export const slugMappings: SlugMapping[] = [ 24 - { 25 - slug: 'blog', 26 - publicationRkey: '3m3x4bgbsh22k' // my blog publication rkey 27 - }, 28 - { 29 - slug: 'cailean', 30 - publicationRkey: '3m4222fxc3k2q' // Cailean Uen's publication rkey for his journal 31 - } 32 - // Add more mappings as needed: 33 - // { slug: 'notes', publicationRkey: 'xyz123abc' }, 34 - // { slug: 'essays', publicationRkey: 'def456ghi' }, 35 - ]; 36 - 37 - /** 38 32 * Get publication rkey from slug 33 + * Automatically normalizes the slug before lookup 34 + * 35 + * @param slug - The slug to look up (will be normalized) 36 + * @returns The publication rkey or null if not found 39 37 */ 40 38 export function getPublicationRkeyFromSlug(slug: string): string | null { 41 - const mapping = slugMappings.find(m => m.slug === slug); 39 + const normalizedSlug = normalizeSlug(slug); 40 + const mapping = slugMappings.find(m => normalizeSlug(m.slug) === normalizedSlug); 42 41 return mapping?.publicationRkey || null; 43 42 } 44 43 45 44 /** 46 45 * Get slug from publication rkey 46 + * 47 + * @param rkey - The publication rkey 48 + * @returns The slug or null if not found 47 49 */ 48 50 export function getSlugFromPublicationRkey(rkey: string): string | null { 49 51 const mapping = slugMappings.find(m => m.publicationRkey === rkey); ··· 51 53 } 52 54 53 55 /** 54 - * Get all configured slugs 56 + * Get all configured slugs (normalized) 57 + * 58 + * @returns Array of normalized slugs 55 59 */ 56 60 export function getAllSlugs(): string[] { 57 - return slugMappings.map(m => m.slug); 61 + return slugMappings.map(m => normalizeSlug(m.slug)); 62 + } 63 + 64 + /** 65 + * Get all slug mappings with normalized slugs 66 + * 67 + * @returns Array of slug mappings with normalized slugs 68 + */ 69 + export function getAllSlugMappings(): SlugMapping[] { 70 + return slugMappings.map(m => ({ 71 + ...m, 72 + slug: normalizeSlug(m.slug) 73 + })); 58 74 }
+41
src/lib/data/slug-mappings.ts
··· 1 + /** 2 + * Slug to Leaflet Publication mapping data 3 + * 4 + * Maps friendly URL slugs to Leaflet publication rkeys. 5 + * This allows you to access publications via /{slug} instead of /blog 6 + * 7 + * Example: 8 + * - /blog → maps to publication with rkey "3m3x4bgbsh22k" 9 + * - /notes → maps to publication with rkey "xyz123abc" 10 + */ 11 + 12 + export interface SlugMapping { 13 + /** The URL-friendly slug (will be normalized automatically) */ 14 + slug: string; 15 + /** The Leaflet publication rkey */ 16 + publicationRkey: string; 17 + } 18 + 19 + /** 20 + * Slug to publication rkey mappings 21 + * Add your custom mappings here 22 + * 23 + * Note: Slugs will be automatically normalized to be URI-compatible: 24 + * - Converted to lowercase 25 + * - Spaces converted to hyphens 26 + * - Special characters removed 27 + * - Multiple hyphens collapsed to single hyphen 28 + */ 29 + export const slugMappings: SlugMapping[] = [ 30 + { 31 + slug: 'blog', 32 + publicationRkey: '3m3x4bgbsh22k' // my blog publication rkey 33 + }, 34 + { 35 + slug: 'cailean', 36 + publicationRkey: '3m4222fxc3k2q' // Cailean Uen's publication rkey for his journal 37 + } 38 + // Add more mappings as needed: 39 + // { slug: 'notes', publicationRkey: 'xyz123abc' }, 40 + // { slug: 'essays', publicationRkey: 'def456ghi' }, 41 + ];