- author pages resolve slug or login and canonicalise to the slug - tag pages, per-page SEO meta and canonicals that keep ?page=N - sitemap source pages the API and builds locs from journal.routes - /rss.xml proxies the API feed with x-forwarded-for - neutral README; version 0.1.0
41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
// Sitemap entries for Journal content. Every loc is built from journal.routes,
|
|
// so moving or disabling a view moves or drops its URLs; nothing hard-codes
|
|
// a path.
|
|
|
|
import { flattenCategories } from './client.ts'
|
|
import { fillJournalPath } from './routes.ts'
|
|
import type { JournalCategory, JournalPost, JournalRoutes } from './types.ts'
|
|
|
|
export interface JournalSitemapEntry {
|
|
loc: string
|
|
lastmod?: string
|
|
}
|
|
|
|
/**
|
|
* One entry per published post (lastmod = updated_at) at routes.post, and one
|
|
* per category of the flattened tree at routes.category. A disabled route
|
|
* contributes nothing.
|
|
*/
|
|
export function buildJournalSitemapEntries(
|
|
posts: readonly JournalPost[],
|
|
categories: readonly JournalCategory[],
|
|
routes: JournalRoutes,
|
|
): JournalSitemapEntry[] {
|
|
const entries: JournalSitemapEntry[] = []
|
|
if (routes.post !== false) {
|
|
for (const post of posts) {
|
|
if (!post.published || !post.slug) continue
|
|
const entry: JournalSitemapEntry = { loc: fillJournalPath(routes.post, { slug: post.slug }) }
|
|
if (post.updated_at) entry.lastmod = post.updated_at
|
|
entries.push(entry)
|
|
}
|
|
}
|
|
if (routes.category !== false) {
|
|
for (const category of flattenCategories(categories)) {
|
|
if (!category.slug) continue
|
|
entries.push({ loc: fillJournalPath(routes.category, { category: category.slug }) })
|
|
}
|
|
}
|
|
return entries
|
|
}
|