Add page routing and content fetchers

This commit is contained in:
itsfinniii
2026-03-15 18:55:30 +01:00
parent bc11be5669
commit 21d5ba23a4
22 changed files with 923 additions and 9 deletions

203
astro/src/lib/pages.ts Normal file
View File

@@ -0,0 +1,203 @@
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",
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: null
};
}
// 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"
}
};
}
// 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",
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];
});
console.log(params);
const photo = await getPhotoFromHash(`/${params["R"]}`, params["H"]);
if (photo === null) {}
return {
route: route,
pageType: "Photo",
page: {
type: "PhotoPage",
id: photo!.id,
photo: photo!.photo,
text: photo!.text
}
};
}
else if (regexToRoute({ template: "/", allowPagination: false }).regex.test(route) ||
regexToRoute({ template: "/%R", allowPagination: false }).regex.test(route)) {
const webpageContent = await getWebpage(route);
return {
route: route,
pageType: "Webpage",
page: webpageContent
};
}
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
};
}

View File

@@ -17,6 +17,15 @@ export async function getAllRoutesList(settings: GlobalSettings): Promise<string
if (settings.blog.enabled) {
const blogs = await getAllBlogs(settings);
for (let i = 0; i < Math.ceil(blogs.length / 6); i++) {
if (i !== 0) {
routes.push(`${settings.blog.indexRouteTemplate}/${i + 1}`);
}
else {
routes.push(settings.blog.indexRouteTemplate);
}
}
blogs.forEach((blog) => {
routes.push(getBlogRoute(settings.blog, blog));
});
@@ -24,6 +33,15 @@ export async function getAllRoutesList(settings: GlobalSettings): Promise<string
if (settings.project.enabled) {
const projects = await getAllProjects(settings);
for (let i = 0; i < Math.ceil(projects.length / 4); i++) {
if (i !== 0) {
routes.push(`${settings.project.indexRouteTemplate}/${i + 1}`);
}
else {
routes.push(settings.project.indexRouteTemplate);
}
}
projects.forEach((project) => {
routes.push(getProjectRoute(settings.project, project));
});
@@ -32,6 +50,8 @@ export async function getAllRoutesList(settings: GlobalSettings): Promise<string
const categories = await getAllCategories(settings);
const galleries = await getAllAlbums(settings);
routes.push(settings.photo.categoryIndex.indexRouteTemplate);
categories.forEach((category) => {
let albums = galleries.filter(g => g.category.id === category.id);
const pages = Math.ceil(albums.length / settings.photo.category.perPage);