Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
77 lines
3.0 KiB
JavaScript
77 lines
3.0 KiB
JavaScript
#!/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, '"')} | Teknav</title>
|
|
<meta name="description" content="${(article.metaDescription || article.subtitle || '').replace(/"/g, '"')}"/>
|
|
<link rel="canonical" href="${canonical}"/>
|
|
${hreflang}
|
|
<meta property="og:title" content="${(article.metaTitle || article.title).replace(/"/g, '"')}"/>
|
|
<meta property="og:description" content="${(article.metaDescription || article.subtitle || '').replace(/"/g, '"')}"/>
|
|
<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, '"')}"/>
|
|
<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`);
|