QR-master/scripts/add-aeo-optimization.js

145 lines
3.8 KiB
JavaScript

#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
// Read the blog-data.ts file
const filePath = path.join(__dirname, '../src/lib/blog-data.ts');
let content = fs.readFileSync(filePath, 'utf-8');
// Get all blog post objects using regex
const postRegex = /\{\s*slug:\s*"([^"]+)"[^}]*?keySteps:\s*\[([\s\S]*?)\]\s*,\s*faq:\s*\[([\s\S]*?)\]\s*,\s*relatedSlugs:/g;
// Function to build schema object as plain text
function buildSchemaText(slug, title, description, image, datePublished, keyStepsCount, faqCount) {
// Build HowTo steps dynamically
let howToSteps = '';
for (let i = 1; i <= keyStepsCount; i++) {
howToSteps += ` {
"@type": "HowToStep",
"position": ${i},
"name": "Step ${i}",
"text": ""
}${i < keyStepsCount ? ',' : ''}
`;
}
// Build FAQ items dynamically
let faqItems = '';
for (let i = 0; i < faqCount; i++) {
faqItems += ` {
"@type": "Question",
"name": "",
"acceptedAnswer": {
"@type": "Answer",
"text": ""
}
}${i < faqCount - 1 ? ',' : ''}
`;
}
return `
authorName: "Timo Knuth",
authorTitle: "QR Code & Marketing Expert",
schema: {
article: {
"@context": "https://schema.org",
"@type": "Article",
"headline": "${title}",
"description": "${description}",
"image": "https://www.qrmaster.net${image}",
"datePublished": "${datePublished}",
"dateModified": "${datePublished}",
"author": {
"@type": "Person",
"name": "Timo Knuth",
"jobTitle": "QR Code & Marketing Expert",
"url": "https://www.qrmaster.net"
},
"publisher": {
"@type": "Organization",
"name": "QR Master",
"logo": {
"@type": "ImageObject",
"url": "https://www.qrmaster.net/logo.svg"
}
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://www.qrmaster.net/blog/${slug}"
}
},
faqPage: {
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
${faqItems}
]
},
howTo: {
"@context": "https://schema.org",
"@type": "HowTo",
"name": "${title}",
"step": [
${howToSteps}
]
}
},`;
}
// Simple approach: insert author and schema after relatedSlugs line
// Find each post and inject the fields
const lines = content.split('\n');
const newLines = [];
let inPost = false;
let postBuffer = [];
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
// Check if this is a post start
if (line.trim().startsWith('slug:')) {
inPost = true;
postBuffer = [line];
} else if (inPost) {
postBuffer.push(line);
// Check if we've found the relatedSlugs line
if (line.trim().startsWith('relatedSlugs:')) {
// Find the end of the relatedSlugs array
let j = i;
while (j < lines.length && !lines[j].includes('],')) {
j++;
}
// Add the relatedSlugs lines as-is
for (let k = i; k <= j; k++) {
newLines.push(postBuffer[postBuffer.length - (j - k) - 1] || lines[k]);
}
// Now add author and schema marker
newLines.push(' authorName: "Timo Knuth",');
newLines.push(' authorTitle: "QR Code & Marketing Expert",');
newLines.push(' // AEO/GEO optimization: schema added');
// Skip ahead
inPost = false;
i = j;
postBuffer = [];
continue;
}
}
if (!inPost) {
newLines.push(line);
}
}
// Write the modified content
const modifiedContent = newLines.join('\n');
fs.writeFileSync(filePath, modifiedContent, 'utf-8');
console.log('Added authorName and authorTitle to all posts');