Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
441 lines
22 KiB
JavaScript
441 lines
22 KiB
JavaScript
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
import { resolve } from 'node:path';
|
|
import { TeknavData } from '../teknav-data.js';
|
|
import { renderStaticFallback, replaceStaticFallback } from './static-fallback.mjs';
|
|
|
|
const SITE_URL = (process.env.TEKNAV_SITE_URL || process.env.VITE_SITE_URL || 'https://www.teknav.ir').replace(/\/$/, '');
|
|
const SITE_NAME = 'تکناو';
|
|
const DEFAULT_IMAGE = `${SITE_URL}/images/og/default.jpg`;
|
|
const DEFAULT_KEYWORDS = 'تکناو, فناوری, هوش مصنوعی, علم داده, امنیت سایبری, نرم افزار, سخت افزار, استارتاپ, آینده فناوری, تحلیل تکنولوژی';
|
|
|
|
const template = readFileSync(resolve('dist/index.html'), 'utf8');
|
|
|
|
function esc(value) {
|
|
return String(value ?? '')
|
|
.replace(/&/g, '&')
|
|
.replace(/"/g, '"')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>');
|
|
}
|
|
|
|
function clean(value) {
|
|
return String(value ?? '').replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
|
|
}
|
|
|
|
function truncate(value, max = 155) {
|
|
const text = clean(value);
|
|
return text.length > max ? `${text.slice(0, max - 1).trim()}…` : text;
|
|
}
|
|
|
|
const org = {
|
|
'@type': ['Organization', 'NewsMediaOrganization'],
|
|
'@id': `${SITE_URL}/#organization`,
|
|
name: 'تکناو',
|
|
alternateName: ['Teknav', 'تکنّاو'],
|
|
url: SITE_URL,
|
|
logo: {
|
|
'@type': 'ImageObject',
|
|
'@id': `${SITE_URL}/#logo`,
|
|
url: `${SITE_URL}/favicon.png`,
|
|
width: 512,
|
|
height: 512,
|
|
},
|
|
image: { '@id': `${SITE_URL}/#logo` },
|
|
};
|
|
|
|
const website = {
|
|
'@type': 'WebSite',
|
|
'@id': `${SITE_URL}/#website`,
|
|
url: SITE_URL,
|
|
name: 'تکناو',
|
|
alternateName: 'Teknav',
|
|
inLanguage: 'fa-IR',
|
|
publisher: { '@id': `${SITE_URL}/#organization` },
|
|
};
|
|
|
|
const GLOSSARY_SAMEAS_MAP = {
|
|
ai: [
|
|
'https://www.wikidata.org/wiki/Q11660',
|
|
'https://fa.wikipedia.org/wiki/%D9%87%D9%88%D8%B4_%D9%85%D8%B5%D9%86%D9%88%D8%B5%DB%8C'
|
|
],
|
|
llm: [
|
|
'https://www.wikidata.org/wiki/Q115305900',
|
|
'https://fa.wikipedia.org/wiki/%D9%85%D8%AF%D9%84_%D8%B2%D8%A8%D8%A7%D9%86%DB%8C_%D8%A8%D8%B2%D8%B1%DA%AF'
|
|
],
|
|
rag: [
|
|
'https://www.wikidata.org/wiki/Q124378129',
|
|
'https://en.wikipedia.org/wiki/Retrieval-augmented_generation'
|
|
],
|
|
'prompt-injection': [
|
|
'https://www.wikidata.org/wiki/Q117409023',
|
|
'https://en.wikipedia.org/wiki/Prompt_injection'
|
|
],
|
|
'vector-database': [
|
|
'https://www.wikidata.org/wiki/Q119790697',
|
|
'https://en.wikipedia.org/wiki/Vector_database'
|
|
],
|
|
'agentic-ai': [
|
|
'https://www.wikidata.org/wiki/Q127415174'
|
|
]
|
|
};
|
|
|
|
function buildBreadcrumb(items) {
|
|
return {
|
|
'@type': 'BreadcrumbList',
|
|
itemListElement: items.map((item, idx) => ({
|
|
'@type': 'ListItem',
|
|
position: idx + 1,
|
|
name: item.name,
|
|
...(item.path ? { item: `${SITE_URL}${item.path}` } : {}),
|
|
})),
|
|
};
|
|
}
|
|
|
|
let count = 0;
|
|
|
|
function writePage(routePath, title, description, keywords, jsonLdGraph) {
|
|
const canonical = `${SITE_URL}${routePath}`;
|
|
const jsonLd = JSON.stringify({
|
|
'@context': 'https://schema.org',
|
|
'@graph': [
|
|
org,
|
|
website,
|
|
...jsonLdGraph,
|
|
]
|
|
});
|
|
|
|
let html = template;
|
|
html = html.replace(/<html lang="[^"]*" dir="[^"]*">/, `<html lang="fa" dir="rtl">`);
|
|
html = html.replace(/<title>[^<]*<\/title>/, `<title>${title}</title>`);
|
|
html = html.replace(/(<meta name="description" content=")[^"]*(")/, `$1${description}$2`);
|
|
html = html.replace(/(<meta name="keywords" content=")[^"]*(")/, `$1${esc(keywords)}$2`);
|
|
html = html.replace(/(<meta name="language" content=")[^"]*(")/, `$1fa-IR$2`);
|
|
html = html.replace(/(<meta property="og:locale" content=")[^"]*(")/, `$1fa_IR$2`);
|
|
html = html.replace(/(<meta property="og:title" content=")[^"]*(")/, `$1${title}$2`);
|
|
html = html.replace(/(<meta property="og:description" content=")[^"]*(")/, `$1${description}$2`);
|
|
html = html.replace(/(<meta property="og:url" content=")[^"]*(")/, `$1${esc(canonical)}$2`);
|
|
html = html.replace(/(<meta property="og:image" content=")[^"]*(")/, `$1${esc(DEFAULT_IMAGE)}$2`);
|
|
html = html.replace(/(<meta name="twitter:title" content=")[^"]*(")/, `$1${title}$2`);
|
|
html = html.replace(/(<meta name="twitter:description" content=")[^"]*(")/,`$1${description}$2`);
|
|
html = html.replace(/(<meta name="twitter:image" content=")[^"]*(")/, `$1${esc(DEFAULT_IMAGE)}$2`);
|
|
html = html.replace(/(<link rel="canonical" href=")[^"]*(")/, `$1${esc(canonical)}$2`);
|
|
html = html.replace(/<link rel="alternate" hreflang="[^"]+" href="[^"]+" \/>/, `<link rel="alternate" hreflang="fa" href="${esc(canonical)}" />`);
|
|
html = html.replace(/<script type="application\/ld\+json">[\s\S]*?<\/script>/,
|
|
`<script type="application/ld+json">${jsonLd}</script>`);
|
|
html = replaceStaticFallback(html, renderStaticFallback({
|
|
eyebrow: 'تکناو',
|
|
title,
|
|
description,
|
|
facts: [
|
|
{ label: 'زبان', value: 'فارسی' },
|
|
{ label: 'نشانی canonical', value: canonical },
|
|
],
|
|
links: [
|
|
{ href: '/', label: SITE_NAME, text: 'صفحه اصلی' },
|
|
{ href: '/articles', label: 'مقالههای فناوری', text: 'آرشیو تحلیلها' },
|
|
{ href: '/authors', label: 'نویسندگان تکناو', text: 'پروفایل نویسندگان' },
|
|
],
|
|
}));
|
|
|
|
// Normalize path format for directory creation
|
|
const relativeDir = routePath.startsWith('/') ? routePath.slice(1) : routePath;
|
|
const localDir = resolve(`dist/${relativeDir}`);
|
|
mkdirSync(localDir, { recursive: true });
|
|
writeFileSync(`${localDir}/index.html`, html, 'utf8');
|
|
count++;
|
|
}
|
|
|
|
// 1. Generate Categories
|
|
for (const category of TeknavData.categories ?? []) {
|
|
const name = category.name;
|
|
const description = category.description || `مقالهها و تحلیلهای فارسی تکناو درباره ${name}.`;
|
|
const path = `/category/${category.slug}`;
|
|
const title = `${name} | مقالهها و تحلیلهای تکناو`;
|
|
const keywords = `${name}, مقاله ${name}, تحلیل ${name}, فناوری, تکناو`;
|
|
|
|
const jsonLdGraph = [
|
|
{
|
|
'@type': 'CollectionPage',
|
|
name,
|
|
description,
|
|
url: `${SITE_URL}${path}`,
|
|
inLanguage: 'fa-IR',
|
|
},
|
|
buildBreadcrumb([
|
|
{ name: SITE_NAME, path: '/' },
|
|
{ name }
|
|
]),
|
|
];
|
|
|
|
writePage(path, title, description, keywords, jsonLdGraph);
|
|
}
|
|
|
|
// 2. Generate Tags
|
|
for (const tag of TeknavData.tags ?? []) {
|
|
const name = tag.name;
|
|
const path = `/tag/${encodeURIComponent(name)}`;
|
|
const title = `برچسب ${name} | مقالههای تکنـاو`;
|
|
const description = `همه مقالههای تکنـاو درباره ${name}، همراه با تحلیل فارسی، داده و مسیرهای مرتبط برای مطالعه بیشتر.`;
|
|
const keywords = `${name}, تکنـاو, مقاله فناوری, تحلیل فناوری`;
|
|
|
|
const jsonLdGraph = [
|
|
{
|
|
'@type': 'CollectionPage',
|
|
name: `برچسب ${name}`,
|
|
url: `${SITE_URL}${path}`,
|
|
inLanguage: 'fa-IR',
|
|
},
|
|
buildBreadcrumb([
|
|
{ name: SITE_NAME, path: '/' },
|
|
{ name: 'برچسبها', path: '/articles' },
|
|
{ name }
|
|
]),
|
|
];
|
|
|
|
writePage(path, title, description, keywords, jsonLdGraph);
|
|
}
|
|
|
|
// 3. Generate Glossary
|
|
for (const term of TeknavData.glossary ?? []) {
|
|
const slug = term.slug;
|
|
const path = `/glossary/${slug}`;
|
|
const title = `${term.term} چیست؟ | فرهنگ واژگان تکنّاو`;
|
|
const description = truncate(term.summary, 155);
|
|
const keywords = `${term.term}, ${term.english || ''}, فرهنگ واژگان فناوری, تکنّاو`;
|
|
const sameAs = GLOSSARY_SAMEAS_MAP[slug] || [];
|
|
|
|
const jsonLdGraph = [
|
|
{
|
|
'@type': 'DefinedTerm',
|
|
name: term.term,
|
|
alternateName: term.english,
|
|
description,
|
|
inDefinedTermSet: `${SITE_URL}/glossary`,
|
|
url: `${SITE_URL}${path}`,
|
|
sameAs,
|
|
},
|
|
term.faqs?.length ? {
|
|
'@type': 'FAQPage',
|
|
mainEntity: term.faqs.map(([q, a]) => ({
|
|
'@type': 'Question',
|
|
name: q,
|
|
acceptedAnswer: { '@type': 'Answer', text: a },
|
|
})),
|
|
} : null,
|
|
buildBreadcrumb([
|
|
{ name: SITE_NAME, path: '/' },
|
|
{ name: 'فرهنگ واژگان', path: '/articles' },
|
|
{ name: term.term }
|
|
]),
|
|
].filter(Boolean);
|
|
|
|
writePage(path, title, description, keywords, jsonLdGraph);
|
|
}
|
|
|
|
// 4. Generate Topics
|
|
for (const topic of TeknavData.topicHubs ?? []) {
|
|
const slug = topic.slug;
|
|
const path = `/topics/${slug}`;
|
|
const name = topic.title;
|
|
const description = topic.description || `مقالهها و تحلیلهای تکناو درباره ${name}.`;
|
|
const title = topic.seoTitle || `${name} | خوشه موضوعی تکناو`;
|
|
const keywords = (topic.keywords ?? [name, 'تکناو', 'تحلیل فناوری']).join(', ');
|
|
|
|
const jsonLdGraph = [
|
|
{
|
|
'@type': 'CollectionPage',
|
|
name,
|
|
description,
|
|
url: `${SITE_URL}${path}`,
|
|
inLanguage: 'fa-IR',
|
|
isPartOf: { '@id': `${SITE_URL}/#website` },
|
|
},
|
|
topic.faqs?.length ? {
|
|
'@type': 'FAQPage',
|
|
mainEntity: topic.faqs.map(([q, a]) => ({
|
|
'@type': 'Question',
|
|
name: q,
|
|
acceptedAnswer: { '@type': 'Answer', text: a },
|
|
})),
|
|
} : null,
|
|
buildBreadcrumb([
|
|
{ name: SITE_NAME, path: '/' },
|
|
{ name: 'موضوعات', path: '/articles' },
|
|
{ name }
|
|
]),
|
|
].filter(Boolean);
|
|
|
|
writePage(path, title, description, keywords, jsonLdGraph);
|
|
}
|
|
|
|
// 5. Generate Series Pages
|
|
for (const series of TeknavData.articleSeries ?? []) {
|
|
const slug = series.slug;
|
|
const path = `/series/${slug}`;
|
|
const name = series.title;
|
|
const description = truncate(series.description || 'سری مقالههای تکناو برای دنبال کردن یک موضوع فناوری بهترتیب تحریریه.', 155);
|
|
const title = `${name} | سری مقالههای تکناو`;
|
|
const keywords = `${name}, سری مقاله, تکناو, تحلیل فناوری`;
|
|
|
|
const jsonLdGraph = [
|
|
{
|
|
'@type': 'CollectionPage',
|
|
name,
|
|
description,
|
|
url: `${SITE_URL}${path}`,
|
|
inLanguage: 'fa-IR',
|
|
},
|
|
buildBreadcrumb([
|
|
{ name: SITE_NAME, path: '/' },
|
|
{ name: 'سری مقالهها', path: '/articles' },
|
|
{ name }
|
|
]),
|
|
];
|
|
|
|
writePage(path, title, description, keywords, jsonLdGraph);
|
|
}
|
|
|
|
// 6. Generate Static / Core Pages
|
|
const staticPages = [
|
|
{
|
|
path: '/articles',
|
|
title: 'مقالههای فناوری | تکناو',
|
|
description: 'آرشیو مقالههای فارسی تکناو درباره هوش مصنوعی، علم داده، امنیت سایبری، نرمافزار، سختافزار و آینده فناوری.',
|
|
keywords: DEFAULT_KEYWORDS,
|
|
jsonLdGraph: [{ '@type': 'CollectionPage', name: 'مقالههای فناوری تکناو', url: `${SITE_URL}/articles`, inLanguage: 'fa-IR' }]
|
|
},
|
|
{
|
|
path: '/authors',
|
|
title: 'نویسندگان تکناو | تحلیلگران فناوری',
|
|
description: 'آشنایی با نویسندگان و تحلیلگران تکناو در حوزه هوش مصنوعی، امنیت سایبری، نرمافزار، سختافزار و استارتاپ.',
|
|
keywords: 'نویسندگان تکناو, تحلیلگر فناوری, نویسنده هوش مصنوعی, نویسنده امنیت سایبری',
|
|
jsonLdGraph: [{ '@type': 'CollectionPage', name: 'نویسندگان تکناو', url: `${SITE_URL}/authors`, inLanguage: 'fa-IR' }]
|
|
},
|
|
{
|
|
path: '/newsletter',
|
|
title: 'آرشیو خبرنامه تکنـاو | تحلیل هفتگی فناوری',
|
|
description: 'آرشیو خبرنامههای ارسالشده تکنـاو درباره هوش مصنوعی، امنیت سایبری، نرمافزار، سختافزار، استارتاپ و داده.',
|
|
keywords: 'خبرنامه تکنـاو, آرشیو خبرنامه فناوری, تحلیل هفتگی فناوری, هوش مصنوعی, امنیت سایبری',
|
|
jsonLdGraph: [
|
|
{ '@type': 'CollectionPage', name: 'آرشیو خبرنامه تکنـاو', url: `${SITE_URL}/newsletter`, inLanguage: 'fa-IR' },
|
|
buildBreadcrumb([{ name: SITE_NAME, path: '/' }, { name: 'خبرنامه' }])
|
|
]
|
|
},
|
|
{
|
|
path: '/jobs',
|
|
title: 'فرصتهای شغلی فناوری | تکناو',
|
|
description: 'آگهیهای شغلی منتخب فناوری و امکان ثبت موقعیت شغلی شرکتها در تکناو.',
|
|
keywords: 'شغل فناوری, استخدام برنامه نویس, استخدام هوش مصنوعی, تکناو جابز',
|
|
jsonLdGraph: [
|
|
{ '@type': 'CollectionPage', name: 'فرصتهای شغلی فناوری | تکناو', url: `${SITE_URL}/jobs`, inLanguage: 'fa-IR', description: 'آگهیهای شغلی منتخب فناوری و امکان ثبت موقعیت شغلی شرکتها در تکناو.' },
|
|
buildBreadcrumb([{ name: SITE_NAME, path: '/' }, { name: 'فرصتهای شغلی فناوری' }])
|
|
]
|
|
},
|
|
{
|
|
path: '/courses',
|
|
title: 'دورههای تخصصی فناوری | تکناو',
|
|
description: 'دورههای فارسی تکناو برای هوش مصنوعی، امنیت، نرمافزار و مهارتهای فنی محصولمحور.',
|
|
keywords: 'دوره فناوری, آموزش هوش مصنوعی, آموزش امنیت, دوره فارسی برنامه نویسی',
|
|
jsonLdGraph: [
|
|
{ '@type': 'CollectionPage', name: 'دورههای تخصصی فناوری | تکناو', url: `${SITE_URL}/courses`, inLanguage: 'fa-IR', description: 'دورههای فارسی تکناو برای هوش مصنوعی، امنیت، نرمافزار و مهارتهای فنی محصولمحور.' },
|
|
buildBreadcrumb([{ name: SITE_NAME, path: '/' }, { name: 'دورههای تخصصی فناوری' }])
|
|
]
|
|
},
|
|
{
|
|
path: '/membership',
|
|
title: 'عضویت پریمیوم تکناو | محتوای اختصاصی فناوری',
|
|
description: 'عضویت پریمیوم تکناو برای تجربه بدون تبلیغ، محتوای اختصاصی و دسترسی بهتر به دورهها و گزارشهای تخصصی.',
|
|
keywords: 'عضویت تکناو, محتوای پریمیوم فناوری, تحلیل اختصاصی فناوری',
|
|
jsonLdGraph: [
|
|
{ '@type': 'CollectionPage', name: 'عضویت پریمیوم تکناو | محتوای اختصاصی فناوری', url: `${SITE_URL}/membership`, inLanguage: 'fa-IR', description: 'عضویت پریمیوم تکناو برای تجربه بدون تبلیغ، محتوای اختصاصی و دسترسی بهتر به دورهها و گزارشهای تخصصی.' },
|
|
buildBreadcrumb([{ name: SITE_NAME, path: '/' }, { name: 'عضویت پریمیوم تکناو' }])
|
|
]
|
|
},
|
|
{
|
|
path: '/about',
|
|
title: 'درباره ما | تکناو',
|
|
description: 'درباره رسانه فارسی تکناو و ماموریت ما در تحلیل فناوری، هوش مصنوعی و امنیت سایبری.',
|
|
keywords: 'درباره تکناو, ماموریت تکناو, رسانه فناوری, تحلیل هوش مصنوعی',
|
|
jsonLdGraph: [
|
|
{ '@type': 'WebPage', '@id': `${SITE_URL}/about#webpage`, name: 'درباره ما | تکناو', description: 'درباره رسانه فارسی تکناو و ماموریت ما در تحلیل فناوری، هوش مصنوعی و امنیت سایبری.', url: `${SITE_URL}/about`, inLanguage: 'fa-IR' },
|
|
buildBreadcrumb([{ name: SITE_NAME, path: '/' }, { name: 'درباره ما' }])
|
|
]
|
|
},
|
|
{
|
|
path: '/contact',
|
|
title: 'تماس با ما | تکناو',
|
|
description: 'ارتباط با تیم تحریریه و پشتیبانی تکناو برای نظرات، پیشنهادات و همکاری.',
|
|
keywords: 'تماس با تکناو, پشتیبانی تکناو, همکاری با تکناو, تبلیغات تکناو',
|
|
jsonLdGraph: [
|
|
{ '@type': 'WebPage', '@id': `${SITE_URL}/contact#webpage`, name: 'تماس با ما | تکناو', description: 'ارتباط با تیم تحریریه و پشتیبانی تکناو برای نظرات، پیشنهادات و همکاری.', url: `${SITE_URL}/contact`, inLanguage: 'fa-IR' },
|
|
buildBreadcrumb([{ name: SITE_NAME, path: '/' }, { name: 'تماس با ما' }])
|
|
]
|
|
},
|
|
{
|
|
path: '/terms',
|
|
title: 'قوانین و مقررات | تکناو',
|
|
description: 'شرایط استفاده و قوانین و مقررات استفاده از محتوا و خدمات رسانه تکناو.',
|
|
keywords: 'قوانین تکناو, مقررات تکناو, شرایط استفاده تکناو',
|
|
jsonLdGraph: [
|
|
{ '@type': 'WebPage', '@id': `${SITE_URL}/terms#webpage`, name: 'قوانین و مقررات | تکناو', description: 'شرایط استفاده و قوانین و مقررات استفاده از محتوا و خدمات رسانه تکناو.', url: `${SITE_URL}/terms`, inLanguage: 'fa-IR' },
|
|
buildBreadcrumb([{ name: SITE_NAME, path: '/' }, { name: 'قوانین و مقررات' }])
|
|
]
|
|
},
|
|
{
|
|
path: '/privacy',
|
|
title: 'حریم خصوصی | تکناو',
|
|
description: 'سیاست حریم خصوصی و نحوه حفاظت از اطلاعات کاربران در رسانه تکناو.',
|
|
keywords: 'حریم خصوصی تکناو, سیاست حریم خصوصی, امنیت اطلاعات کاربران',
|
|
jsonLdGraph: [
|
|
{ '@type': 'WebPage', '@id': `${SITE_URL}/privacy#webpage`, name: 'حریم خصوصی | تکناو', description: 'سیاست حریم خصوصی و نحوه حفاظت از اطلاعات کاربران در رسانه تکناو.', url: `${SITE_URL}/privacy`, inLanguage: 'fa-IR' },
|
|
buildBreadcrumb([{ name: SITE_NAME, path: '/' }, { name: 'حریم خصوصی' }])
|
|
]
|
|
},
|
|
{
|
|
path: '/tools',
|
|
title: 'ابزارهای تخصصی فناوری | تکناو',
|
|
description: 'جعبهابزار تخصصی تکناو برای توسعهدهندگان، مهندسان داده و تحلیلگران؛ شامل نرمالساز متن و ماشینحساب RAG.',
|
|
keywords: 'ابزار توسعه دهنده, نرمال ساز متن, ماشین حساب RAG, جعبه ابزار تکناو',
|
|
jsonLdGraph: [
|
|
{ '@type': 'CollectionPage', name: 'ابزارهای تخصصی فناوری | تکناو', url: `${SITE_URL}/tools`, inLanguage: 'fa-IR', description: 'جعبهابزار تخصصی تکناو برای توسعهدهندگان، مهندسان داده و تحلیلگران؛ شامل نرمالساز متن و ماشینحساب RAG.' },
|
|
buildBreadcrumb([{ name: SITE_NAME, path: '/' }, { name: 'ابزارها' }])
|
|
]
|
|
},
|
|
{
|
|
path: '/tools/nlp-normalizer',
|
|
title: 'نرمالساز متن فارسی (NLP) | ابزارهای تکناو',
|
|
description: 'ابزار تخصصی پاکسازی، نیمفاصلهگذاری و پیشپردازش متن فارسی برای تسکهای پردازش زبان طبیعی و مدلهای زبانی.',
|
|
keywords: 'نرمال ساز متن فارسی, نیم فاصله گذاری, پیش پردازش متن فارسی, NLP فارسی',
|
|
jsonLdGraph: [
|
|
{ '@type': 'WebPage', '@id': `${SITE_URL}/tools/nlp-normalizer#webpage`, name: 'نرمالساز متن فارسی (NLP) | ابزارهای تکناو', description: 'ابزار تخصصی پاکسازی، نیمفاصلهگذاری و پیشپردازش متن فارسی برای تسکهای پردازش زبان طبیعی و مدلهای زبانی.', url: `${SITE_URL}/tools/nlp-normalizer`, inLanguage: 'fa-IR' },
|
|
buildBreadcrumb([{ name: SITE_NAME, path: '/' }, { name: 'ابزارها', path: '/tools' }, { name: 'نرمالساز متن فارسی' }])
|
|
]
|
|
},
|
|
{
|
|
path: '/tools/rag-calculator',
|
|
title: 'ماشینحساب ظرفیت و هزینه RAG | ابزارهای تکناو',
|
|
description: 'ماشینحساب تخصصی محاسبه تعداد توکن، فضای پایگاهداده برداری، هزینههای استنتاج LLM و پهنای باند معماری RAG.',
|
|
keywords: 'هزینه RAG, ماشین حساب RAG, پهنای باند RAG, پایگاه داده برداری',
|
|
jsonLdGraph: [
|
|
{ '@type': 'WebPage', '@id': `${SITE_URL}/tools/rag-calculator#webpage`, name: 'ماشینحساب ظرفیت و هزینه RAG | ابزارهای تکناو', description: 'ماشینحساب تخصصی محاسبه تعداد توکن، فضای پایگاهداده برداری، هزینههای استنتاج LLM و پهنای باند معماری RAG.', url: `${SITE_URL}/tools/rag-calculator`, inLanguage: 'fa-IR' },
|
|
buildBreadcrumb([{ name: SITE_NAME, path: '/' }, { name: 'ابزارها', path: '/tools' }, { name: 'ماشینحساب RAG' }])
|
|
]
|
|
},
|
|
{
|
|
path: '/tekrag-persian',
|
|
title: 'بنچمارک TekRag | ارزیابی سامانههای RAG فارسی',
|
|
description: 'درگاه رسمی بنچمارک TekRag؛ اولین فریمورک استاندارد ارزیابی دقت، بازیابی و پاسخدهی سیستمهای RAG زبان فارسی.',
|
|
keywords: 'TekRag benchmark, بنچمارک RAG فارسی, ارزیابی سیستم RAG, هوش مصنوعی فارسی',
|
|
jsonLdGraph: [
|
|
{ '@type': 'WebPage', '@id': `${SITE_URL}/tekrag-persian#webpage`, name: 'بنچمارک TekRag | ارزیابی سامانههای RAG فارسی', description: 'درگاه رسمی بنچمارک TekRag؛ اولین فریمورک استاندارد ارزیابی دقت، بازیابی و پاسخدهی سیستمهای RAG زبان فارسی.', url: `${SITE_URL}/tekrag-persian`, inLanguage: 'fa-IR' },
|
|
buildBreadcrumb([{ name: SITE_NAME, path: '/' }, { name: 'بنچمارک TekRag' }])
|
|
]
|
|
}
|
|
];
|
|
|
|
for (const pg of staticPages) {
|
|
writePage(pg.path, pg.title, pg.description, pg.keywords, pg.jsonLdGraph);
|
|
}
|
|
|
|
console.log(`[semantic-pages] generated ${count} static semantic HTML pages`);
|