Import source: global/scripts/generate-article-pages.mjs

Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
arsam
2026-09-18 23:27:07 +03:30
parent c162c85fb1
commit fb2d237d45
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env node
// Generates static HTML for each article under dist/article/{slug}/index.html
import { readFileSync, writeFileSync, mkdirSync } from 'fs';
import { articles, authors, siteConfig } from '../global-data.js';
const SITE = siteConfig.url;
const template = readFileSync('dist/index.html', 'utf8');
function capDate(d) {
const now = new Date().toISOString().split('T')[0];
return d > now ? now : d;
}
let count = 0;
for (const article of articles) {
const author = authors.find(a => a.id === article.author);
const canonical = `${SITE}/article/${article.slug}`;
const ogImage = `${SITE}${article.photo}`;
const lastmod = capDate(article.dateEn);
const jsonLd = JSON.stringify({
'@context': 'https://schema.org',
'@type': ['NewsArticle', 'TechArticle'],
headline: article.metaTitle || article.title,
description: article.metaDescription || article.subtitle,
image: ogImage,
datePublished: article.dateEn,
dateModified: lastmod,
inLanguage: 'en',
isAccessibleForFree: true,
mainEntityOfPage: { '@type': 'WebPage', '@id': canonical },
author: author ? {
'@type': 'Person',
name: author.name,
url: `${SITE}/author/${author.slug}`,
} : undefined,
publisher: {
'@type': ['Organization', 'NewsMediaOrganization'],
name: 'Teknav',
url: SITE,
logo: { '@type': 'ImageObject', url: `${SITE}/images/og/default.jpg` },
},
});
const hreflang = article.persianUrl
? `<link rel="alternate" hreflang="fa" href="${article.persianUrl}"/>
<link rel="alternate" hreflang="en" href="${canonical}"/>
<link rel="alternate" hreflang="x-default" href="${article.persianUrl}"/>`
: '';
const head = `
<title>${(article.metaTitle || article.title).replace(/"/g, '&quot;')} | Teknav</title>
<meta name="description" content="${(article.metaDescription || article.subtitle || '').replace(/"/g, '&quot;')}"/>
<link rel="canonical" href="${canonical}"/>
${hreflang}
<meta property="og:title" content="${(article.metaTitle || article.title).replace(/"/g, '&quot;')}"/>
<meta property="og:description" content="${(article.metaDescription || article.subtitle || '').replace(/"/g, '&quot;')}"/>
<meta property="og:image" content="${ogImage}"/>
<meta property="og:url" content="${canonical}"/>
<meta property="og:type" content="article"/>
<meta property="og:locale" content="en_US"/>
${article.persianUrl ? `<meta property="og:locale:alternate" content="fa_IR"/>` : ''}
<meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:title" content="${(article.metaTitle || article.title).replace(/"/g, '&quot;')}"/>
<meta name="twitter:image" content="${ogImage}"/>
<script type="application/ld+json">${jsonLd}</script>`;
const html = template.replace('</head>', `${head}\n </head>`);
const dir = `dist/article/${article.slug}`;
mkdirSync(dir, { recursive: true });
writeFileSync(`${dir}/index.html`, html);
count++;
}
console.log(`[article-pages] generated ${count} static article HTML pages`);