site: rename "finds" superpost collection to "bundles"
Disambiguates the one-letter `find` (item) vs `finds` (roundup) split that
kept causing confusion. Audience-facing now: `/bundles/<slug>/`, "Bundle"
labels in home/footer/search.
Internals: `getCollection('finds')` → `('bundles')`, `Entry.type 'finds'`
→ `'bundle'`, `OgFallback 'finds'` → `'bundles'`, `findListMosaic` →
`bundleMosaic`, `FindsPost` → `Bundle`, `findsReferencing` →
`bundlesReferencing`. Build script + generated mosaic dir follow
(`scripts/build-bundle-mosaics.mjs`, `src/generated/bundle-mosaics/`).
Skills `build-finds` → `build-bundle`, `cluster-finds` →
`cluster-bundles`. The `find` collection (individual items) is unchanged.
No URL redirects: low external-link surface area.
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { getCollection, type CollectionEntry } from 'astro:content';
|
||||
|
||||
export type FindsPost = CollectionEntry<'finds'>;
|
||||
export type Bundle = CollectionEntry<'bundles'>;
|
||||
|
||||
export async function findsReferencing(slug: string): Promise<FindsPost[]> {
|
||||
const all = await getCollection('finds');
|
||||
export async function bundlesReferencing(slug: string): Promise<Bundle[]> {
|
||||
const all = await getCollection('bundles');
|
||||
return all
|
||||
.filter((p) => p.data.items.includes(slug))
|
||||
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import type { ImageMetadata } from 'astro';
|
||||
|
||||
const modules = import.meta.glob<{ default: ImageMetadata }>(
|
||||
'../generated/list-mosaics/*.jpg',
|
||||
'../generated/bundle-mosaics/*.jpg',
|
||||
{ eager: true }
|
||||
);
|
||||
|
||||
const mosaics = new Map<string, ImageMetadata>();
|
||||
for (const [path, mod] of Object.entries(modules)) {
|
||||
const match = path.match(/list-mosaics\/([^/]+)\.jpg$/);
|
||||
const match = path.match(/bundle-mosaics\/([^/]+)\.jpg$/);
|
||||
if (match) mosaics.set(match[1], mod.default);
|
||||
}
|
||||
|
||||
export function findListMosaic(slug: string): ImageMetadata | undefined {
|
||||
export function bundleMosaic(slug: string): ImageMetadata | undefined {
|
||||
return mosaics.get(slug);
|
||||
}
|
||||
+10
-10
@@ -1,7 +1,7 @@
|
||||
import { getCollection } from 'astro:content';
|
||||
|
||||
export type Entry = {
|
||||
type: 'review' | 'post' | 'finds';
|
||||
type: 'review' | 'post' | 'bundle';
|
||||
id: string;
|
||||
href: string;
|
||||
date: Date;
|
||||
@@ -14,7 +14,7 @@ export type Entry = {
|
||||
export async function getAllEntries(): Promise<Entry[]> {
|
||||
const reviews = await getCollection('reviews');
|
||||
const posts = await getCollection('posts');
|
||||
const findsPosts = await getCollection('finds');
|
||||
const bundles = await getCollection('bundles');
|
||||
|
||||
const r: Entry[] = reviews.map((e) => ({
|
||||
type: 'review',
|
||||
@@ -37,10 +37,10 @@ export async function getAllEntries(): Promise<Entry[]> {
|
||||
primary: e.data.title,
|
||||
}));
|
||||
|
||||
const f: Entry[] = findsPosts.map((e) => ({
|
||||
type: 'finds',
|
||||
const b: Entry[] = bundles.map((e) => ({
|
||||
type: 'bundle',
|
||||
id: e.id,
|
||||
href: `/finds/${e.id}/`,
|
||||
href: `/bundles/${e.id}/`,
|
||||
date: e.data.date,
|
||||
category: e.data.category,
|
||||
tags: e.data.tags,
|
||||
@@ -48,7 +48,7 @@ export async function getAllEntries(): Promise<Entry[]> {
|
||||
secondary: e.data.blurb,
|
||||
}));
|
||||
|
||||
return [...r, ...p, ...f].sort((a, b) => b.date.valueOf() - a.date.valueOf());
|
||||
return [...r, ...p, ...b].sort((a, b) => b.date.valueOf() - a.date.valueOf());
|
||||
}
|
||||
|
||||
export type SiteStats = {
|
||||
@@ -57,7 +57,7 @@ export type SiteStats = {
|
||||
reviews: number;
|
||||
finds: number;
|
||||
posts: number;
|
||||
lists: number;
|
||||
bundles: number;
|
||||
};
|
||||
|
||||
let statsCache: Promise<SiteStats> | null = null;
|
||||
@@ -73,17 +73,17 @@ async function computeSiteStats(): Promise<SiteStats> {
|
||||
const reviews = entries.filter((e) => e.type === 'review').length;
|
||||
const finds = findItems.length;
|
||||
const posts = entries.filter((e) => e.type === 'post').length;
|
||||
const lists = entries.filter((e) => e.type === 'finds').length;
|
||||
const bundles = entries.filter((e) => e.type === 'bundle').length;
|
||||
const allDates = [
|
||||
...entries.map((e) => e.date),
|
||||
...findItems.map((f) => f.data.date),
|
||||
].sort((a, b) => b.valueOf() - a.valueOf());
|
||||
return {
|
||||
total: reviews + finds + posts + lists,
|
||||
total: reviews + finds + posts + bundles,
|
||||
lastUpdated: allDates[0] ?? null,
|
||||
reviews,
|
||||
finds,
|
||||
posts,
|
||||
lists,
|
||||
bundles,
|
||||
};
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
import { heroes } from './hero';
|
||||
import type { OgImage } from '../components/SEO.astro';
|
||||
|
||||
export type OgFallback = 'reviews' | 'finds' | 'posts' | 'site';
|
||||
export type OgFallback = 'reviews' | 'bundles' | 'posts' | 'site';
|
||||
|
||||
const SITE_URL = 'https://unique.rzen.dev';
|
||||
|
||||
const FALLBACK_PATHS: Record<OgFallback, string> = {
|
||||
reviews: '/og/reviews.png',
|
||||
finds: '/og/finds.png',
|
||||
bundles: '/og/bundles.png',
|
||||
posts: '/og/posts.png',
|
||||
site: '/og/default.png',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user