Newer
Older
#!/usr/bin/env node
"use strict";
const fs = require("fs");
const browserify = require("browserify");
.pipe(fs.createWriteStream(`${curDir}/public/main.js`));
function getPageHtml(pageName, pageMeta) {
let html = fs.readFileSync(`${curDir}/public/index.html`, "utf-8");
const setMeta = function (metaName, value) {
html.match(new RegExp(`<meta\\s*name="${metaName}"[^>]+>`, "g"))[0],
const setTitle = function () {
html = html.replace(
html.match(new RegExp(`<title.+</title>`, "g"))[0],
`<title>${pageMeta.title}</title>`
html.match(new RegExp(`<h1.+</h1>`, "g")),
`<h1 style="visibility: hidden">${pageMeta.title}</h1>`
html = html.replace(
html.match(new RegExp(`<link.+/style.css[^>]+>`, "g"))[0],
`<link href="/style/style.css" rel="stylesheet" />`
);
};
const setJs = function () {
html = html.replace(
html.match(new RegExp(`<script.+main.js.+</script>`, "g"))[0],
`<script type="text/javascript" src="./${pageName}.js"></script>`
);
};
"</head>",
`${metas
.map(kv => {
const [name, content] = kv;
return `<meta name="${name}" content="${content}"/>`;
})
.join("\n")}</head>`
);
};
const setOgMeta = function () {
const pageOgMeta = pageMeta.open_graph || {};
const getOgMetaSearchRegex = function (name) {
return new RegExp(`<meta\\s*property="og:${name}"[^>]+>`, "g");
};
const getDefaultOgMetaContent = function (name) {
const getRegexMatch = function (source, searchRe) {
const m = source.match(searchRe);
return m ? m[0] : "";
};
return getRegexMatch(
getRegexMatch(
getRegexMatch(html, getOgMetaSearchRegex(name)),
new RegExp(`content=".+"`, "g")
),
new RegExp(`".+"`, "g")
).replace(/"/g, "");
};
const requiredOgMeta = [
{ key: "title", defaultValue: pageMeta.title },
{ key: "description", defaultValue: pageMeta.description },
{
key: "image",
defaultValue: pageMeta.image || getDefaultOgMetaContent("image"),
},
{
key: "url",
defaultValue: (function () {
const urlContent = getDefaultOgMetaContent("url");
return `${urlContent}${urlContent.charAt(urlContent.length - 1) !== "/" ? "/" : ""
}${pageName}`;
})(),
},
{
key: "locale",
defaultValue: getDefaultOgMetaContent("locale"),
},
// TODO : handle locale:alternate meta tags array
];
requiredOgMeta.forEach(entry => {
const { key, defaultValue } = entry;
html = html.replace(
html.match(getOgMetaSearchRegex(key)),
(function () {
const customValue = pageOgMeta[key];
if (!customValue)
return `<meta property="og:${key}" content="${defaultValue}"/>`;
else {
return Array.isArray(customValue)
? customValue
.map(alt => `<meta property="og:${key}" content="${alt}"/>`)
.join("\n")
: `<meta property="og:${key}" content="${customValue}"/>`;
}
})()
const additionalOgMeta = Object.keys(pageMeta.open_graph).filter(
k => !requiredOgMeta.map(rom => rom.key).includes(k)
);
if (additionalOgMeta.length > 0) {
html = html.replace(
"</head>",
`${additionalOgMeta
.map(k => `<meta property="og:${k}" content="${pageMeta.open_graph[k]}"/>`)
const setJsonLdScript = function () {
const jsonLd = pageMeta.json_ld;
html = html.replace(
html.match(new RegExp(`<script.+json.+>[^<]+</script>`, "g"))[0],
`<script type="application/ld+json">${JSON.stringify(jsonLd)}</script>`
);
};
setTitle();
setStyleSheet();
setJs();
setAdditionalMeta(
Object.entries(pageMeta).filter(kv => !build_conf.default_meta_keys.includes(kv[0]))
// set twitter image
html = html.replace(
html.match(new RegExp(`<meta\\s*property="twitter:image"[^>]+>`, "g"))[0],
`<meta property="twitter:image" content="${pageMeta.image ||
html
.match(new RegExp(`<meta\\s*name="image"[^>]+>`, "g"))[0]
.match(new RegExp(`content=".+"`, "g"))[0]
.match(new RegExp(`".+"`, "g"))
.replace(/"/g, "")
function createPages(rootdir, destdir) {
const pages = fs.readdirSync(rootdir);
for (const p of pages) {
const fPath = `${rootdir}/${p}`;
const targetDirPath = `${destdir}/${p}`;
if (!fs.existsSync(targetDirPath)) {
fs.mkdirSync(targetDirPath);
}
b.add(fPath)
.bundle()
.pipe(fs.createWriteStream(`${targetDirPath}/${p}.js`));
const page = fs.createWriteStream(`${targetDirPath}/index.html`);
const pageMeta = JSON.parse(fs.readFileSync(`${fPath}/meta.json`, "utf-8"));
page.write(getPageHtml(p, pageMeta));
if (fs.existsSync(`${fPath}/subpages`)) {
createPages(`${fPath}/subpages`, targetDirPath)
}
}
// If pages have been deleted in source, remove them in output directory too.
for (const dir of fs.readdirSync(destdir).filter(f => {
if (build_conf.protected_dirs.includes(f)) return false;
const stats = fs.statSync(`${destdir}/${f}`);
return stats.isDirectory();
})) {
if (!pages.includes(dir)) {
const dPath = `${destdir}/${dir}`;
try {
const nestedFiles = fs.readdirSync(dPath);
for (const nf of nestedFiles) {
fs.unlinkSync(`${dPath}/${nf}`);
}
fs.rmdirSync(dPath);
} catch (error) {
console.error(error);
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
createPages(`${curDir}/src/pages`, `${curDir}/public`);
// const pages = fs.readdirSync(`${curDir}/src/pages`);
// for (const p of pages) {
// const fPath = `${curDir}/src/pages/${p}`;
// const targetDirPath = `${curDir}/public/${p}`;
// if (!fs.existsSync(targetDirPath)) {
// fs.mkdirSync(targetDirPath);
// }
// const b = browserify();
// b.add(fPath)
// .bundle()
// .pipe(fs.createWriteStream(`${targetDirPath}/${p}.js`));
// const page = fs.createWriteStream(`${targetDirPath}/index.html`);
// const pageMeta = JSON.parse(fs.readFileSync(`${fPath}/meta.json`, "utf-8"));
// page.write(getPageHtml(p, pageMeta));
// }
// // If pages have been deleted in source, remove them in output directory too.
// for (const dir of fs.readdirSync(`${curDir}/public`).filter(f => {
// if (build_conf.protected_dirs.includes(f)) return false;
// const stats = fs.statSync(`${curDir}/public/${f}`);
// return stats.isDirectory();
// })) {
// if (!pages.includes(dir)) {
// const dPath = `${curDir}/public/${dir}`;
// try {
// const nestedFiles = fs.readdirSync(dPath);
// for (const nf of nestedFiles) {
// fs.unlinkSync(`${dPath}/${nf}`);
// }
// fs.rmdirSync(dPath);
// } catch (error) {
// console.error(error);
// }
// }
// }