const oils = require('../data/taxonomy/oils.json'); const concerns = require('../data/taxonomy/concerns.json'); const LOCALES = ['sr', 'en', 'de', 'fr']; const DEFAULT_LOCALE = 'sr'; function generateUrl(oilId, concernId, locale) { const oil = oils.oils[oilId]; const concern = concerns.concerns[concernId]; if (!oil || !concern) return null; const localePrefix = locale === DEFAULT_LOCALE ? '' : `/${locale}`; const oilSlug = oil.slug[locale]; const concernSlug = concern.slug[locale]; return { url: `${localePrefix}/solutions/${oilSlug}-for-${concernSlug}`, canonical: `https://manoonoils.com${localePrefix}/solutions/${oilSlug}-for-${concernSlug}`, locale, oil: { id: oilId, name: oil.name[locale], slug: oilSlug }, concern: { id: concernId, name: concern.name[locale], slug: concernSlug } }; } function generateAllUrls() { const urls = []; const stats = { total: 0, byLocale: {}, byOil: {}, byConcern: {} }; LOCALES.forEach(l => stats.byLocale[l] = 0); Object.keys(oils.oils).forEach(o => stats.byOil[o] = 0); Object.keys(concerns.concerns).forEach(c => stats.byConcern[c] = 0); for (const oilId of Object.keys(oils.oils)) { const oil = oils.oils[oilId]; for (const concernId of oil.concerns) { const concern = concerns.concerns[concernId]; if (!concern) { console.warn(`Warning: Concern ${concernId} not found for oil ${oilId}`); continue; } for (const locale of LOCALES) { const urlData = generateUrl(oilId, concernId, locale); if (urlData) { urls.push(urlData); stats.total++; stats.byLocale[locale]++; stats.byOil[oilId]++; stats.byConcern[concernId]++; } } } } return { urls, stats }; } function generateSitemap() { const { urls } = generateAllUrls(); let sitemap = '\n'; sitemap += '\n'; for (const url of urls) { sitemap += ' \n'; sitemap += ` ${url.canonical}\n`; sitemap += ' weekly\n'; sitemap += ' 0.8\n'; sitemap += ` \n`; sitemap += ' \n'; } sitemap += ''; return sitemap; } function generateUrlReport() { const { urls, stats } = generateAllUrls(); let report = '# Programmatic SEO URL Report\n\n'; report += `Generated: ${new Date().toISOString()}\n\n`; report += '## Summary\n\n'; report += `- **Total URLs**: ${stats.total}\n`; report += `- **Languages**: ${LOCALES.join(', ')}\n`; report += `- **Oils**: ${Object.keys(oils.oils).length}\n`; report += `- **Concerns**: ${Object.keys(concerns.concerns).length}\n\n`; report += '## URLs by Locale\n\n'; for (const [locale, count] of Object.entries(stats.byLocale)) { report += `- **${locale.toUpperCase()}**: ${count} URLs\n`; } report += '\n'; report += '## URLs by Oil\n\n'; for (const [oilId, count] of Object.entries(stats.byOil)) { const oil = oils.oils[oilId]; report += `- **${oil.name.en}** (${oilId}): ${count} URLs\n`; } report += '\n'; report += '## URLs by Concern\n\n'; for (const [concernId, count] of Object.entries(stats.byConcern)) { const concern = concerns.concerns[concernId]; report += `- **${concern.name.en}** (${concernId}): ${count} URLs\n`; } report += '\n'; report += '## All Generated URLs\n\n'; const urlsByOil = {}; for (const url of urls) { if (!urlsByOil[url.oil.id]) { urlsByOil[url.oil.id] = []; } urlsByOil[url.oil.id].push(url); } for (const [oilId, oilUrls] of Object.entries(urlsByOil)) { const oil = oils.oils[oilId]; report += `### ${oil.name.en}\n\n`; const byConcern = {}; for (const url of oilUrls) { if (!byConcern[url.concern.id]) { byConcern[url.concern.id] = []; } byConcern[url.concern.id].push(url); } for (const [concernId, concernUrls] of Object.entries(byConcern)) { const concern = concerns.concerns[concernId]; report += `#### ${concern.name.en}\n\n`; for (const url of concernUrls) { report += `- ${url.locale.toUpperCase()}: \`${url.canonical}\`\n`; } report += '\n'; } } return report; } module.exports = { generateUrl, generateAllUrls, generateSitemap, generateUrlReport, LOCALES, DEFAULT_LOCALE }; if (require.main === module) { const { urls, stats } = generateAllUrls(); console.log('\n=== PROGRAMMATIC SEO URL GENERATOR ===\n'); console.log(`Total URLs Generated: ${stats.total}`); console.log('\nBy Locale:'); for (const [locale, count] of Object.entries(stats.byLocale)) { console.log(` ${locale.toUpperCase()}: ${count}`); } console.log('\nBy Oil:'); for (const [oilId, count] of Object.entries(stats.byOil)) { const oil = oils.oils[oilId]; console.log(` ${oil.name.en}: ${count}`); } console.log('\nBy Concern:'); for (const [concernId, count] of Object.entries(stats.byConcern)) { const concern = concerns.concerns[concernId]; console.log(` ${concern.name.en}: ${count}`); } console.log('\n=== SAMPLE URLS ===\n'); const sampleUrls = urls.filter((_, i) => i < 12); for (const url of sampleUrls) { console.log(`${url.locale.toUpperCase()}: ${url.canonical}`); } const fs = require('fs'); const report = generateUrlReport(); fs.writeFileSync('./url-report.md', report); console.log('\nāœ“ Full report saved to: url-report.md'); const sitemap = generateSitemap(); fs.writeFileSync('./sitemap-programmatic.xml', sitemap); console.log('āœ“ Sitemap saved to: sitemap-programmatic.xml'); }