summaryrefslogtreecommitdiff
path: root/src/build/index.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'src/build/index.mjs')
-rw-r--r--src/build/index.mjs208
1 files changed, 127 insertions, 81 deletions
diff --git a/src/build/index.mjs b/src/build/index.mjs
index c7e1cf7..a14cdc7 100644
--- a/src/build/index.mjs
+++ b/src/build/index.mjs
@@ -1,104 +1,150 @@
+import process from 'node:process';
import fs from 'node:fs';
import mustache from 'mustache';
-import {u} from 'unist-builder';
-import {h} from 'hastscript';
-import {select} from 'hast-util-select';
-import {toString as hastToString} from 'mdast-util-to-string';
-import cssesc from 'cssesc';
-
-import {toHtmlRaw, toString, toMdRaw, mdToHtmlRaw} from './to-html.mjs';
import loadSVG from './load-svg.mjs';
-import listArticles from './list-articles.mjs';
import getRSS from './rss.mjs';
-import toml from '@ltd/j-toml';
-
-const loadMD = (listFile, suffix) => {
- const listContent = [];
- for (const file of listFile) {
- console.log(`Working on ${file}`);
- const content = fs.readFileSync(`${suffix}/${file}`, 'utf8');
- const mdRaw = toMdRaw(content);
- const tomlStringValue = mdRaw.children[0].value;
- const metaData = toml.parse(tomlStringValue);
- const newHTML = mdToHtmlRaw(mdRaw);
-
- const htmlContent = newHTML;
- const htmlRender = toString(htmlContent);
-
- const titleHtml = select('h1', htmlContent);
- const intro = select('p', htmlContent);
- intro.children = intro.children.filter(child => child.tagName !== 'br');
-
- const logo = select('img', intro);
- logo.properties.src = `${suffix}/${logo.properties.src}`;
- logo.properties.height = '150';
- logo.properties.width = '150';
- titleHtml.children[0].properties.href = `${suffix}/${file.slice(0, -3)}`;
-
- const title = hastToString(titleHtml);
- const domTitle = cssesc(title.replace(/\s+/g, '-').replace(/['"#@]/, '').toLowerCase()); // Maybe encodeURI
-
- const readMore = h('a', 'Lire plus...');
-
- readMore.properties.href = `${suffix}/${file.slice(0, -3)}`;
-
- listContent.push({
- name: file.slice(0, -3),
- content: htmlRender,
- intro: toString(u('root', [titleHtml, intro, readMore])),
- introDesc: hastToString(intro),
- imageUrl: logo.properties.src,
- metaData,
- title,
- domTitle,
- });
- }
+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'
- return listContent;
-};
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();
-const articles = loadMD(listArticles, 'articles');
+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]);
+ }
+ }
+ }
-for (const article of articles) {
- const context = {
- svg,
- title: `${article.title} - ache`,
- canonical: baseUrl + article.domTitle,
- content: article.content,
- domTitle: article.domTitle,
- };
- const output = mustache.render(articleTmpl, context, partials);
+// 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});
+ }
- console.log(`Create : ${article.title}`);
- fs.writeFileSync(`articles/${article.name}.html`, output);
-}
+ 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.xml');
-const xmlFeed = getRSS(articles, baseUrl);
-fs.writeFileSync('rss.xml', xmlFeed);
-
-{
- const context = {
- title: 'ache: Blog personnel',
- canonical: baseUrl,
- svg,
- articles,
- };
-
- console.log('Create : Home page');
- const output = mustache.render(indexTmpl, context, partials);
- fs.writeFileSync('index.html', output);
+ 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)
+);
+