Files
website/astro/src/lib/pages.ts
2026-03-20 16:55:33 +01:00

232 lines
7.7 KiB
TypeScript

import { getBlog } from "@/content/blogs/blogs";
import { getWebpage } from "@/content/pages/pages";
import { getAlbum } from "@/content/photos/albums";
import { getPhotoFromHash } from "@/content/photos/photos";
import { getProject } from "@/content/projects/projects";
export async function getPage(settings: GlobalSettings, route: string): Promise<PageType | null> {
// Blog Index
if (regexToRoute({ template: settings.blog.indexRouteTemplate, allowPagination: true }).regex.test(route)) {
const { regex, keys } = regexToRoute({ template: settings.blog.indexRouteTemplate, allowPagination: true });
const match = route.match(regex);
const params: Record<string, string> = {};
if (!match) return null;
keys.forEach((key, i) => {
params[key] = match[i + 1];
});
return {
route: route,
pageType: "BlogIndex",
page: {
type: "BlogIndex",
exists: true,
pageNumber: params["page"] !== undefined ? Number(params["page"]) : 1
}
};
}
// Blog Post
else if (regexToRoute({ template: settings.blog.blogRouteTemplate, allowPagination: false }).regex.test(route)) {
const { regex, keys } = regexToRoute({ template: settings.blog.blogRouteTemplate, allowPagination: false });
const match = route.match(regex);
const params: Record<string, string> = {};
if (!match) return null;
keys.forEach((key, i) => {
params[key] = match[i + 1];
});
const blog = await getBlog(settings, `/${params["R"]}`);
return {
route: route,
pageType: "BlogPost",
page: blog
};
}
// Project Index
else if (regexToRoute({ template: settings.project.indexRouteTemplate, allowPagination: true }).regex.test(route)) {
const { regex, keys } = regexToRoute({ template: settings.project.indexRouteTemplate, allowPagination: true });
const match = route.match(regex);
const params: Record<string, string> = {};
if (!match) return null;
keys.forEach((key, i) => {
params[key] = match[i + 1];
});
return {
route: route,
pageType: "ProjectIndex",
page: {
type: "ProjectIndex",
exists: true,
pageNumber: params["page"] !== undefined ? Number(params["page"]) : 1
}
};
}
// Project Post
else if (regexToRoute({ template: settings.project.projectRouteTemplate, allowPagination: false }).regex.test(route)) {
const { regex, keys } = regexToRoute({ template: settings.project.projectRouteTemplate, allowPagination: false });
const match = route.match(regex);
const params: Record<string, string> = {};
if (!match) return null;
keys.forEach((key, i) => {
params[key] = match[i + 1];
});
const project = await getProject(settings, `/${params["R"]}`);
return {
route: route,
pageType: "ProjectPost",
page: project
};
}
// Photo Category Index
else if (regexToRoute({ template: settings.photo.categoryIndex.indexRouteTemplate, allowPagination: false }).regex.test(route)) {
return {
route: route,
pageType: "PhotoCategoryIndex",
page: {
type: "PhotoCategoryIndex",
exists: true
}
};
}
// Photo Category / Album List
else if (regexToRoute({ template: settings.photo.category.routeTemplate, allowPagination: true }).regex.test(route)) {
const { regex, keys } = regexToRoute({ template: settings.photo.category.routeTemplate, allowPagination: true });
const match = route.match(regex);
const params: Record<string, string> = {};
if (!match) return null;
keys.forEach((key, i) => {
params[key] = match[i + 1];
});
return {
route: route,
pageType: "PhotoCategory",
page: {
type: "PhotoCategory",
exists: true,
category: params["category"],
pageNumber: params["page"] !== undefined ? Number(params["page"]) : 1
}
};
}
// Photo Album
else if (regexToRoute({ template: settings.photo.album.routeTemplate, allowPagination: true }).regex.test(route)) {
const { regex, keys } = regexToRoute({ template: settings.photo.album.routeTemplate, allowPagination: true });
const match = route.match(regex);
const params: Record<string, string> = {};
if (!match) return null;
keys.forEach((key, i) => {
params[key] = match[i + 1];
});
const photoAlbum = await getAlbum(settings, `/${params["R"]}`);
return {
route: route,
pageType: "PhotoAlbum",
page: photoAlbum
};
}
// Photograph
else if (regexToRoute({ template: settings.photo.photo.routeTemplate, allowPagination: false }).regex.test(route)) {
const { regex, keys } = regexToRoute({ template: settings.photo.photo.routeTemplate, allowPagination: false });
const match = route.match(regex);
const params: Record<string, string> = {};
if (!match) return null;
keys.forEach((key, i) => {
params[key] = match[i + 1];
});
const photo = await getPhotoFromHash(`/${params["R"]}`, params["H"]);
if (photo === null) {}
return {
route: route,
pageType: "Photo",
page: {
type: "PhotoPage",
exists: true,
id: photo!.id,
photo: photo!.photo,
text: photo!.text
}
};
}
// Regular webpage
else if (regexToRoute({ template: "/", allowPagination: false }).regex.test(route) ||
regexToRoute({ template: "/%R", allowPagination: false }).regex.test(route)) {
const webpageContent = await getWebpage(route);
if (webpageContent === null || !webpageContent.exists) {
return {
route: route,
pageType: "Webpage",
page: {
type: "Webpage",
exists: false
}
}
}
return {
route: route,
pageType: "Webpage",
page: {
type: "Webpage",
exists: true,
id: webpageContent.id,
lastModified: webpageContent.lastModified,
url: webpageContent.url,
searchEngine: webpageContent.searchEngine,
components: webpageContent.components
}
};
}
else {
return null;
}
}
function regexToRoute(template: PageRegexMatchProps) {
const keys: string[] = [];
let pattern = template.template
.replaceAll("%Y", () => { keys.push("Y"); return "(\\d{4})"; })
.replaceAll("%M", () => { keys.push("M"); return "(\\d{2})"; })
.replaceAll("%D", () => { keys.push("D"); return "(\\d{2})"; })
.replaceAll("%R", () => { keys.push("R"); return "([^/]+)"; })
.replaceAll("%C", () => { keys.push("C"); return "([^/]+)"; })
.replaceAll("%H", () => { keys.push("H"); return "([^/]+)"; })
.replace(/\/+/g, "/");
if (template.allowPagination) {
keys.push("page");
pattern += "(?:\\/(\\d+))?";
}
return {
regex: new RegExp(`^${pattern}$`),
keys
};
}