Files
teknav-bak/app/scripts/generate-en-page.mjs
T
arsam d0d37d1a36 Import source: app/scripts/generate-en-page.mjs
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
2026-09-18 23:23:29 +03:30

124 lines
6.4 KiB
JavaScript

import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import { resolve } from 'node:path';
const SITE_URL = (process.env.TEKNAV_SITE_URL || process.env.VITE_SITE_URL || 'https://www.teknav.ir').replace(/\/$/, '');
const distRoot = resolve('dist');
const sourcePath = resolve(distRoot, 'index.html');
const targetDir = resolve(distRoot, 'en');
const targetPath = resolve(targetDir, 'index.html');
function esc(value) {
return String(value ?? '')
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
function json(value) {
return JSON.stringify(value).replace(/</g, '\\u003c');
}
const canonical = `${SITE_URL}/en/`;
const title = 'Teknav English | Persian Technology Analysis on AI, Data, Security and Software';
const description = 'Teknav English homepage: a single LTR English gateway to Persian technology analysis on AI, data science, cybersecurity, software, hardware, startups, writers, and the newsletter archive.';
const keywords = [
'Teknav English',
'Teknav',
'Persian technology media',
'Iran technology analysis',
'Persian AI articles',
'Persian data science',
'Persian cybersecurity',
'AI analysis Iran',
'technology writers Iran',
'Persian tech newsletter',
'RAG benchmark Persian',
'data-centric AI Persian',
'software engineering analysis',
'hardware analysis',
'startup analysis Iran',
].join(', ');
const image = `${SITE_URL}/images/og/tekrag-persian-data-centric-rag-benchmark.jpg`;
const graph = [
{
'@context': 'https://schema.org',
'@type': ['Organization', 'NewsMediaOrganization'],
'@id': `${SITE_URL}/#organization-en`,
name: 'Teknav',
alternateName: ['Teknav.ir', 'Teknav English'],
url: SITE_URL,
logo: { '@type': 'ImageObject', url: `${SITE_URL}/favicon.png`, width: 512, height: 512 },
description: 'Teknav is a Persian-first technology publication covering artificial intelligence, data science, cybersecurity, software engineering, hardware, startups, and future technology.',
sameAs: ['https://x.com/teknavir', 'https://linkedin.com/company/teknav'],
},
{
'@context': 'https://schema.org',
'@type': 'WebSite',
'@id': `${SITE_URL}/en/#website`,
url: canonical,
name: 'Teknav English',
inLanguage: 'en-US',
publisher: { '@id': `${SITE_URL}/#organization-en` },
description,
potentialAction: {
'@type': 'SearchAction',
target: `${SITE_URL}/search?q={search_term_string}`,
'query-input': 'required name=search_term_string',
},
},
{
'@context': 'https://schema.org',
'@type': 'WebPage',
'@id': `${SITE_URL}/en/#webpage`,
name: 'Teknav English',
url: canonical,
inLanguage: 'en-US',
isPartOf: { '@id': `${SITE_URL}/en/#website` },
primaryImageOfPage: { '@type': 'ImageObject', url: image },
about: [
{ '@type': 'Thing', name: 'Artificial Intelligence' },
{ '@type': 'Thing', name: 'Data Science' },
{ '@type': 'Thing', name: 'Cybersecurity' },
{ '@type': 'Thing', name: 'Software Engineering' },
{ '@type': 'Thing', name: 'Persian technology analysis' },
],
},
{
'@context': 'https://schema.org',
'@type': 'BreadcrumbList',
itemListElement: [
{ '@type': 'ListItem', position: 1, name: 'Teknav', item: SITE_URL },
{ '@type': 'ListItem', position: 2, name: 'English', item: canonical },
],
},
];
let html = readFileSync(sourcePath, 'utf8');
html = html.replace(/<html([^>]*)>/, '<html lang="en" dir="ltr">');
html = html.replace(/<title>.*?<\/title>/, `<title>${esc(title)}</title>`);
html = html.replace(/<meta name="description" content="[^"]*" \/>/, `<meta name="description" content="${esc(description)}" />`);
html = html.replace(/<meta name="keywords" content="[^"]*" \/>/, `<meta name="keywords" content="${esc(keywords)}" />`);
html = html.replace(/<meta name="author" content="[^"]*" \/>/, '<meta name="author" content="Teknav" />');
html = html.replace(/<meta name="language" content="[^"]*" \/>/, '<meta name="language" content="en-US" />');
html = html.replace(/<meta property="og:locale" content="[^"]*" \/>/, '<meta property="og:locale" content="en_US" />');
html = html.replace(/<meta property="og:site_name" content="[^"]*" \/>/, '<meta property="og:site_name" content="Teknav" />');
html = html.replace(/<meta property="og:type" content="[^"]*" \/>/, '<meta property="og:type" content="website" />');
html = html.replace(/<meta property="og:title" content="[^"]*" \/>/, `<meta property="og:title" content="${esc(title)}" />`);
html = html.replace(/<meta property="og:description" content="[^"]*" \/>/, `<meta property="og:description" content="${esc(description)}" />`);
html = html.replace(/<meta property="og:url" content="[^"]*" \/>/, `<meta property="og:url" content="${esc(canonical)}" />`);
html = html.replace(/<meta property="og:image" content="[^"]*" \/>/, `<meta property="og:image" content="${esc(image)}" />`);
html = html.replace(/<meta name="twitter:title" content="[^"]*" \/>/, `<meta name="twitter:title" content="${esc(title)}" />`);
html = html.replace(/<meta name="twitter:description" content="[^"]*" \/>/, `<meta name="twitter:description" content="${esc(description)}" />`);
html = html.replace(/<meta name="twitter:image" content="[^"]*" \/>/, `<meta name="twitter:image" content="${esc(image)}" />`);
html = html.replace(/<link rel="canonical" href="[^"]*" \/>/, `<link rel="canonical" href="${esc(canonical)}" />`);
html = html.replace(/<link rel="alternate" hreflang="[^"]+" href="[^"]+" \/>/, `<link rel="alternate" hreflang="en" href="${esc(canonical)}" />\n <link rel="alternate" hreflang="fa" href="${esc(SITE_URL)}/" />\n <link rel="alternate" hreflang="x-default" href="${esc(canonical)}" />`);
html = html.replace(/<link rel="alternate" type="application\/rss\+xml" title="[^"]*" href="[^"]*" \/>/, `<link rel="alternate" type="application/rss+xml" title="Teknav latest articles" href="${esc(SITE_URL)}/feed.xml" />`);
html = html.replace(/<script type="application\/ld\+json">.*?<\/script>/s, `<script type="application/ld+json">${json({ '@context': 'https://schema.org', '@graph': graph })}</script>`);
html = html.replace(/<div style="font-size:36px;font-weight:900;color:#0F6B73;margin-bottom:8px">.*?<\/div>/, '<div style="font-size:36px;font-weight:900;color:#0F6B73;margin-bottom:8px">Teknav</div>');
mkdirSync(targetDir, { recursive: true });
writeFileSync(targetPath, html, 'utf8');
console.log('[en-page] generated dist/en/index.html');