properish build system, drop hash-based routing
This commit is contained in:
128
index.js
128
index.js
@@ -1,8 +1,49 @@
|
||||
import { load } from "cheerio";
|
||||
import { readFile, writeFile } from "fs";
|
||||
import { readFile, writeFileSync, mkdirSync, cpSync, rmSync } from "fs";
|
||||
import process from "child_process";
|
||||
import stores from "./stores.json" with { type: "json" };
|
||||
|
||||
function mkDir(path) {
|
||||
try {
|
||||
return mkdirSync(path)
|
||||
} catch (err) {
|
||||
if (err.code !== 'EEXIST') throw err
|
||||
}
|
||||
}
|
||||
|
||||
function writeFile(path, content) {
|
||||
try {
|
||||
writeFileSync(path, content);
|
||||
} catch (err) {
|
||||
if (err) throw err;
|
||||
}
|
||||
console.log(`${path} updated.`);
|
||||
}
|
||||
|
||||
function slugify(str) {
|
||||
return str
|
||||
.toLowerCase()
|
||||
.replace(/é/g, "e")
|
||||
.replace(/&/g, " and ")
|
||||
.replace(/ /g, "-")
|
||||
.replace(/[']+/g, "")
|
||||
.replace(/[^\w-]+/g, "-")
|
||||
.replace(/-+/g, "-")
|
||||
.replace(/^-|-$/g, "");
|
||||
}
|
||||
|
||||
function cleanWebsite(str) {
|
||||
return str
|
||||
.toLowerCase()
|
||||
.replace(/^https?:\/\//g, "")
|
||||
.replace(/^www./g, "")
|
||||
.replace(/\/$/g, "");
|
||||
}
|
||||
|
||||
function metaDescription({meta, description}) {
|
||||
return meta || description.length > 155 ? description.slice(0, 153) + "..." : description || "A guide to and map of every independent bookstore in New York City. We have a complete list of community bookstores in NYC with locations and descriptions."
|
||||
}
|
||||
|
||||
function GetRecentChanges() {
|
||||
const res = process
|
||||
.execSync('git log -15 --pretty=format:"%ct %s"')
|
||||
@@ -44,15 +85,68 @@ function TableViewTemplate(rows) {
|
||||
return table + "</table>";
|
||||
}
|
||||
|
||||
function TableRowTemplate({ rowNumber, name, address, city }) {
|
||||
function TableRowTemplate({ rowNumber, name, slug, address, city }) {
|
||||
return `
|
||||
<tr id="${rowNumber}" class="spotRow">
|
||||
<td class="name">${name}</td>
|
||||
<td>${address}, ${city}</td>
|
||||
<td class="name"><a href="/${slugify(name)}/">${name}</a></td>
|
||||
<td><a href="/${slugify(name)}/">${address}, ${city}</a></td>
|
||||
</tr>`;
|
||||
}
|
||||
|
||||
readFile("./index.html", function (err, data) {
|
||||
function TitleTemplate({ name }) {
|
||||
return `${name} | Independent Bookstores in New York City - Best Community Bookstores in NYC`;
|
||||
}
|
||||
|
||||
function SelectedStoreTemplate({
|
||||
name,
|
||||
address,
|
||||
city,
|
||||
postcode,
|
||||
website,
|
||||
events,
|
||||
cafe,
|
||||
description,
|
||||
}) {
|
||||
return `
|
||||
<h2>${name}</h2>
|
||||
<p class="address">${address}</p>
|
||||
<p></p>
|
||||
<p class="address">
|
||||
${city}, NY ${postcode}
|
||||
</p>
|
||||
<p>
|
||||
View in:
|
||||
<a
|
||||
href="https://maps.google.com/maps?q=${encodeURIComponent(
|
||||
name
|
||||
)}+${address},${city},NY"
|
||||
target="_blank"
|
||||
>Google Maps</a
|
||||
>
|
||||
<a
|
||||
href="http://maps.apple.com/?q=${encodeURIComponent(
|
||||
name
|
||||
)}&address=${address},${city},NY"
|
||||
target="_blank"
|
||||
>Apple Maps</a
|
||||
>
|
||||
</p>
|
||||
<ul>
|
||||
${
|
||||
website
|
||||
? `<li><a href="${website}" target="_blank">${cleanWebsite(
|
||||
website
|
||||
)}</a></li>`
|
||||
: ""
|
||||
}
|
||||
<li class="storeDetails">Events: ${events}</li>
|
||||
<li class="storeDetails">Café: ${cafe}</li>
|
||||
</ul>
|
||||
${description ? `<p class="description">${description}</p>` : ""}`;
|
||||
}
|
||||
|
||||
|
||||
readFile("./index.tmpl.html", function (err, data) {
|
||||
const changeList = GetRecentChanges();
|
||||
if (err) {
|
||||
throw err;
|
||||
@@ -77,8 +171,26 @@ readFile("./index.html", function (err, data) {
|
||||
$("#changesList").html(ChangeLog(changeList));
|
||||
const cssurl = $("link[type='text/css']").attr("href").split("?")[0];
|
||||
$("link[type='text/css']").attr("href", cssurl + "?" + new Date().getTime());
|
||||
writeFile("./index.html", $.html(), (err) => {
|
||||
if (err) throw err;
|
||||
console.log("Default view updated.");
|
||||
|
||||
rmSync("./build", { recursive: true, force: true });
|
||||
|
||||
mkDir("./build")
|
||||
|
||||
writeFile("./build/index.html", $.html())
|
||||
|
||||
cpSync("./site.css", "./build/site.css");
|
||||
cpSync("./robots.txt", "./build/robots.txt");
|
||||
cpSync("./img", "./build/img", {recursive: true});
|
||||
cpSync("./stores.json", "./build/stores.json");
|
||||
|
||||
stores.forEach((store) => {
|
||||
$("#selected").html(SelectedStoreTemplate(store));
|
||||
$("#info").addClass("hidden");
|
||||
let title = TitleTemplate(store);
|
||||
$("title").html(title);
|
||||
$("meta[name='title']").attr("content", title);
|
||||
$("meta[name='description']").attr("content", metaDescription(store));
|
||||
mkDir(`./build/${slugify(store.name)}`);
|
||||
writeFile(`./build/${slugify(store.name)}/index.html`, $.html());
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user