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);
createPages(`${curDir}/src/pages`, `${curDir}/public`);