Nieuwe reviews Loes en Verble, geplande publicatie op vrijdag, tabel-wrap
- Reviews Loes (AI-chatassistent) en Verble (AI-speechwriter) toegevoegd, incl. screenshots en logo's - new-review.mjs: publicatiedatum automatisch op eerstvolgende vrijdag na de laatste review (wekelijkse cadans) - publish.ts: geplande reviews blijven zichtbaar in dev-mode, ongeacht datum - rehype-wrap-tables.mjs: brede tabellen (prijsvergelijkingen) scrollen nu horizontaal i.p.v. de pagina te verbreken - Fiskr-publicatiedatum bijgewerkt
This commit is contained in:
@@ -29,7 +29,7 @@
|
||||
*/
|
||||
import { chromium } from "playwright";
|
||||
import Anthropic from "@anthropic-ai/sdk";
|
||||
import { mkdir, readFile, writeFile, access } from "node:fs/promises";
|
||||
import { mkdir, readFile, writeFile, access, readdir } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
@@ -45,6 +45,54 @@ function slugify(hostname) {
|
||||
.replace(/(^-|-$)/g, "");
|
||||
}
|
||||
|
||||
/** YYYY-MM-DD in lokale tijd (middaguur om DST-randen te vermijden). */
|
||||
function formatYmd(d) {
|
||||
const y = d.getFullYear();
|
||||
const m = String(d.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(d.getDate()).padStart(2, "0");
|
||||
return `${y}-${m}-${day}`;
|
||||
}
|
||||
|
||||
function parseYmd(s) {
|
||||
const [y, m, d] = s.split("-").map(Number);
|
||||
return new Date(y, m - 1, d, 12, 0, 0, 0);
|
||||
}
|
||||
|
||||
/** Schuif door tot de eerstvolgende vrijdag (blijft staan als 't al vrijdag is). */
|
||||
function toFriday(d) {
|
||||
const out = new Date(d);
|
||||
const day = out.getDay(); // 0 zo … 5 vr
|
||||
if (day !== 5) out.setDate(out.getDate() + ((5 - day + 7) % 7));
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publicatiedatum voor een nieuw concept: laatste reviewdatum + 1 week,
|
||||
* afgerond naar vrijdag (wekelijkse cadans). Geen eerdere datum? → eerstvolgende vrijdag.
|
||||
*/
|
||||
async function nextPublishDate() {
|
||||
const dir = path.join(projectRoot, "src", "content", "reviews");
|
||||
const files = await readdir(dir);
|
||||
let latest = null;
|
||||
|
||||
for (const file of files) {
|
||||
if (!file.endsWith(".md") || file.startsWith("_")) continue;
|
||||
const text = await readFile(path.join(dir, file), "utf-8");
|
||||
// Alleen een echte frontmatter-date: "date: 2026-07-31" (geen commentaarregel)
|
||||
const match = text.match(/^---\r?\n[\s\S]*?^date:\s*(\d{4}-\d{2}-\d{2})\b/m);
|
||||
if (!match) continue;
|
||||
if (!latest || match[1] > latest) latest = match[1];
|
||||
}
|
||||
|
||||
if (latest) {
|
||||
const d = parseYmd(latest);
|
||||
d.setDate(d.getDate() + 7);
|
||||
return formatYmd(toFriday(d));
|
||||
}
|
||||
|
||||
return formatYmd(toFriday(new Date()));
|
||||
}
|
||||
|
||||
function fillField(template, field, value) {
|
||||
// Laat de regel (met het voorbeeld in de comment) ongewijzigd als er niets gevonden is,
|
||||
// zodat de gebruiker nog steeds ziet wat er verwacht wordt en het zelf kan invullen.
|
||||
@@ -222,17 +270,17 @@ async function main() {
|
||||
// instructie-comment bovenaan het template hoort niet in een echt reviewbestand
|
||||
content = content.replace(/# Kopieer dit bestand[\s\S]*?koppeltekens\.\n\n/, "");
|
||||
|
||||
// date/score horen pas een echte waarde te krijgen bij het publiceren. Het
|
||||
// template zet ze op respectievelijk "" en 0 als leesbaar voorbeeld voor de
|
||||
// handmatige workflow, maar allebei zijn dat *ongeldige* waarden voor het
|
||||
// Zod-schema (date: "" faalt de date-coercion, score: 0 faalt min(1)) — dus
|
||||
// hier uitcommentariëren i.p.v. laten staan, zodat het veld echt afwezig is
|
||||
// (de .optional() in het schema kan er dan mee uit de voeten) maar er wél
|
||||
// zichtbaar blijft staan HOE je 'm moet invullen zodra je gaat publiceren.
|
||||
// Publicatiedatum: laatste bestaande review + 1 week, op vrijdag (cadans).
|
||||
// draft blijft true tot je zelf klaar bent; de datum staat al klaar voor planning.
|
||||
const publishDate = await nextPublishDate();
|
||||
content = content.replace(
|
||||
/^date: ""(\s*#.*)?$/m,
|
||||
"# date: 2026-01-01 # invullen zodra je draft: false zet",
|
||||
`date: ${publishDate} # auto: laatste review + 1 week (vrijdag)`,
|
||||
);
|
||||
console.error(`Publicatiedatum: ${publishDate} (laatste review + 1 week, vrijdag)`);
|
||||
|
||||
// score: 0 is ongeldig voor het Zod-schema (min(1)) — uitcommentariëren zodat
|
||||
// het veld afwezig is (optional zolang draft) maar de invulinstructie blijft.
|
||||
content = content.replace(
|
||||
/^score: 0(\s*#.*)?$/m,
|
||||
"# score: 3 # geheel getal 1-5 (aantal robots) — invullen vóórdat je draft: false zet",
|
||||
|
||||
Reference in New Issue
Block a user