import process from "node:process"; import fs from "node:fs"; import mustache from "mustache"; import loadSVG from "./load-svg.mjs"; import getRSS from "./rss.mjs"; import loadMD from "./loadMD.mjs"; import { cmpArticles } from "./article.mjs"; import i18n from "./i18n.mjs"; import { addDescription } from "./i18n.mjs"; import { minifyHTML } from "./utils.mjs"; import { SitemapStream, streamToPromise } from "sitemap"; import { Readable } from "stream"; const leftPanelTmpl = fs.readFileSync("src/templates/left.tmpl", "utf8"); const likesTmpl = fs.readFileSync("src/templates/likes.tmpl", "utf8"); const headerTmpl = fs.readFileSync("src/templates/header.tmpl", "utf8"); const articleTmpl = fs.readFileSync("src/templates/article.tmpl", "utf8"); const indexTmpl = fs.readFileSync("src/templates/index.tmpl", "utf8"); const tagTmpl = fs.readFileSync("src/templates/tag.tmpl", "utf8"); const hidTmpl = fs.readFileSync("src/templates/hid.tmpl", "utf8"); const baseUrl = "https://ache.one/"; const partials = { header: headerTmpl, leftPanel: leftPanelTmpl, likesButton: likesTmpl, hid: hidTmpl, }; // Load global variables const svg = loadSVG(); let links = []; for (const lang in i18n) { const tagsArticle = new Map(); const filter = process.argv.slice(2); const listArticle = filter.length > 0 ? i18n[lang].articles.filter((article) => filter.includes(article.name)) : i18n[lang].articles; const articles = loadMD(listArticle, "articles", lang); for (const article of articles) { const context = { svg, page_title: `${article.title} - ache`, title: i18n[lang].title, intro: i18n[lang].intro, lang, canonical: `${baseUrl}${article.url.slice(1)}`, content: article.content, title: i18n[lang].title, metaData: article.metaData, alt_lang: addDescription(article.metaData.alt_lang), description: article.intro, like_title: i18n[lang].like_title, like_text: i18n[lang].like_text, }; const output = mustache.render(articleTmpl, context, partials); console.log(`Create : ${article.title}`); fs.writeFileSync(`articles/${article.name}.html`, minifyHTML(output)); links.push({ url: context.canonical, changefreq: "yearly", priority: 0.6, img: [{ url: article.imageUrl }], }); for (const tag of article.metaData.tags) { if (tagsArticle.has(tag)) { tagsArticle.get(tag).push(article); } else { tagsArticle.set(tag, [article]); } } } // Set of pages language dependant try { fs.mkdirSync(`${lang}/tag`, { recursive: true }); } catch { fs.rmSync(`${lang}/tag`, { force: true, recursive: true }); fs.mkdirSync(`${lang}/tag`, { recursive: true }); } for (const [tag, articles] of tagsArticle.entries()) { console.log(`Create tag page : ${lang}/${tag}.html`); articles.sort(cmpArticles); const context = { svg, page_title: `ache - Tag: ${tag}`, title: i18n[lang].title, intro: i18n[lang].intro, lang, tag, articles, description: `${i18n[lang]["tag_desc"]} ${tag}.`, }; const output = mustache.render(tagTmpl, context, partials); fs.writeFileSync(`${lang}/tag/${tag}.html`, minifyHTML(output)); links.push({ url: `${baseUrl}${lang}/tag/${tag}`, changefreq: "monthly", priority: 0.3, }); } console.log(`Create RSS Flux: ${lang}/rss.xml`); const xmlFeed = getRSS(articles, baseUrl, lang); fs.writeFileSync(`${lang}/rss.xml`, xmlFeed); links.push({ url: `${baseUrl}${lang}/rss.xml`, changefreq: "monthly", priority: 0.3, }); { const alt_lang = { fr: { lang: "en", url: "/en/", }, en: { lang: "fr", url: "/fr/", }, }; const context = { page_title: i18n[lang].title.main, title: i18n[lang].title, intro: i18n[lang].intro, lang, canonical: `${baseUrl}${lang}`, svg, articles, alt_lang: [alt_lang[lang]], description: i18n[lang].index_desc, }; console.log(`Create : Home page ${lang}`); const output = mustache.render(indexTmpl, context, partials); fs.writeFileSync(`${lang}/index.html`, minifyHTML(output)); links.push({ url: `${baseUrl}${lang}`, changefreq: "monthly", priority: 0.7, img: [{ url: "https://ache.one/res/ache.svg" }], }); } } console.log(`Create: sitemap.xml`); // Create a stream to write to const stream = new SitemapStream({ hostname: "https://ache.one" }); // Return a promise that resolves with your XML string streamToPromise(Readable.from(links).pipe(stream)) .then((data) => data.toString()) .then((sitemapXML) => fs.writeFileSync("sitemap.xml", sitemapXML));