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) );