shadowfacts.net/lib/generate/tutorials.ts

120 lines
3.4 KiB
TypeScript

import { promises as fs } from "fs";
import path from "path";
import dateFns from "date-fns";
import formatDate from "date-fns/format";
import slugify from "@sindresorhus/slugify";
import { Page, PostMetadata } from "../metadata";
import * as metadata from "../metadata";
import * as markdown from "../markdown";
import layout from "../layout";
import * as util from "../util";
import ejs from "ejs";
async function generateTutorials(group: string): Promise<Page[]> {
const tutorials: Page[] = [];
const files = await fs.readdir(`site/tutorials/${group}`);
for (const f of files) {
let page = await metadata.get(path.join("site/tutorials", group, f));
if (!(<PostMetadata>page.metadata).permalink) {
let postMeta = <PostMetadata>page.metadata;
postMeta.date = dateFns.parse(postMeta.date);
postMeta.slug = postMeta.slug || slugify(postMeta.title);
postMeta.permalink = `/tutorials/${group}/${postMeta.slug}/`;
}
if (page.metadata.source && page.metadata.source!.endsWith(".md")) {
page.text = markdown.render(page.text);
}
const renderedText = await layout(page.text, page.metadata, page.metadata.layout || "article.html.ejs");
let dest = page.metadata.permalink;
if (dest.endsWith("/")) {
dest += "index.html";
}
util.write(dest, renderedText);
tutorials.push(page);
}
return tutorials;
}
export interface TutorialSeries {
index: Page;
posts: Page[];
series: string;
seriesName: string;
}
interface TutorialIndexMetadata extends PostMetadata {
lastUpdated?: Date;
group?: string;
}
async function generateTutorialsAndIndex(group: string, title: string): Promise<TutorialSeries> {
let tutorials = await generateTutorials(group);
tutorials = tutorials.sort((a, b) => {
const aDate = <Date>(<PostMetadata>a.metadata).date;
const bDate = <Date>(<PostMetadata>b.metadata).date;
return aDate.getTime() - bDate.getTime();
});
const page = await metadata.get("site/tutorial-series.html.ejs");
(<PostMetadata>page.metadata).permalink = `/tutorials/${group}/`;
(<PostMetadata>page.metadata).title = title;
(<TutorialIndexMetadata>page.metadata).group = group;
(<TutorialIndexMetadata>page.metadata).lastUpdated = <Date>(<PostMetadata>tutorials[tutorials.length - 1].metadata).date
page.text = ejs.render(page.text, {
tutorials,
metadata: page.metadata,
formatDate,
fancyLink: util.fancyLink
}, {
filename: "site/tutorial-series.html.ejs"
});
page.text = await layout(page.text, page.metadata, page.metadata.layout!);
util.write(path.join("tutorials", group, "index.html"), page.text);
return {
index: page,
posts: tutorials,
series: group,
seriesName: title
};
}
async function generateIndex(allSeries: TutorialSeries[]) {
const page = await metadata.get("site/tutorials.html.ejs");
page.text = ejs.render(page.text, {
allSeries,
formatDate,
fancyLink: util.fancyLink
}, {
filename: "site/tutorials.html.ejs"
});
page.text = await layout(page.text, page.metadata, page.metadata.layout!);
util.write("tutorials/index.html", page.text);
}
export default async function tutorials(): Promise<TutorialSeries[]> {
const series = [
await generateTutorialsAndIndex("forge-modding-1102", "Forge Mods for 1.10.2"),
await generateTutorialsAndIndex("forge-modding-1112", "Forge Mods for 1.11.2"),
await generateTutorialsAndIndex("forge-modding-112", "Forge Mods for 1.12")
];
generateIndex(series);
return series;
}