135 lines
4.4 KiB
JavaScript
135 lines
4.4 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
|
|
|
|
const WORDPRESS_API = 'https://wp.mistergeek.net/wp-json/wp/v2';
|
|
const OUTPUT_DIR = path.join(__dirname, '..', 'data', 'wordpress');
|
|
const HUGO_DATA_DIR = path.join(__dirname, '..', 'data');
|
|
|
|
async function fetchAll(endpoint, perPage = 100) {
|
|
let page = 1;
|
|
let items = [];
|
|
|
|
while (true) {
|
|
const url = `${WORDPRESS_API}/${endpoint}?page=${page}&per_page=${perPage}&_embed`;
|
|
const response = await fetch(url);
|
|
|
|
// If endpoint does not support paging or returns empty, break
|
|
if (!response.ok) {
|
|
// 400 often means "page out of range" for WP; stop paging
|
|
if (response.status === 400) break;
|
|
throw new Error(`Failed to fetch ${endpoint} (page ${page}): ${response.status} ${response.statusText}`);
|
|
}
|
|
|
|
const batch = await response.json();
|
|
items = items.concat(batch);
|
|
|
|
const totalPages = parseInt(response.headers.get('x-wp-totalpages') || '1', 10);
|
|
if (page >= totalPages) break;
|
|
page++;
|
|
}
|
|
|
|
return items;
|
|
}
|
|
|
|
async function generateData() {
|
|
// Ensure output directory exists
|
|
if (!fs.existsSync(OUTPUT_DIR)) {
|
|
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
|
}
|
|
|
|
console.log('Fetching WordPress data...');
|
|
|
|
// Fetch all relevant endpoints concurrently (pages + posts + taxonomies + users)
|
|
const [
|
|
posts,
|
|
pages,
|
|
categories,
|
|
tags,
|
|
authors
|
|
] = await Promise.all([
|
|
fetchAll('posts'),
|
|
fetchAll('pages'),
|
|
fetchAll('categories'),
|
|
fetchAll('tags'),
|
|
fetchAll('users')
|
|
]);
|
|
|
|
// Filter pages to only include published pages
|
|
const publishedPages = pages.filter(page => page.status === 'publish');
|
|
|
|
// Create navigation data from published pages
|
|
const navigationData = publishedPages.map(page => ({
|
|
id: page.id,
|
|
title: page.title?.rendered || page.slug,
|
|
slug: page.slug,
|
|
link: page.link,
|
|
date: page.date,
|
|
modified: page.modified
|
|
}));
|
|
|
|
// Create author-post mapping
|
|
const authorPosts = {};
|
|
posts.forEach(post => {
|
|
if (post.status === 'publish') {
|
|
const author = post._embedded?.author?.[0];
|
|
if (author) {
|
|
const authorSlug = author.slug;
|
|
if (!authorPosts[authorSlug]) {
|
|
authorPosts[authorSlug] = {
|
|
id: author.id,
|
|
name: author.name,
|
|
slug: author.slug,
|
|
description: author.description || '',
|
|
avatar: author.avatar_urls || {},
|
|
link: author.link,
|
|
posts: []
|
|
};
|
|
}
|
|
authorPosts[authorSlug].posts.push({
|
|
id: post.id,
|
|
title: post.title.rendered,
|
|
slug: post.slug,
|
|
date: post.date,
|
|
excerpt: post.excerpt.rendered,
|
|
featured_image: post._embedded?.['wp:featuredmedia']?.[0]?.source_url || '',
|
|
categories: (post._embedded?.['wp:term']?.[0] || []).map(cat => ({
|
|
id: cat.id,
|
|
name: cat.name,
|
|
slug: cat.slug
|
|
})),
|
|
tags: (post._embedded?.['wp:term']?.[1] || []).map(tag => ({
|
|
id: tag.id,
|
|
name: tag.name,
|
|
slug: tag.slug
|
|
}))
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
// Save data as JSON files
|
|
fs.writeFileSync(path.join(OUTPUT_DIR, 'posts.json'), JSON.stringify(posts, null, 2));
|
|
fs.writeFileSync(path.join(OUTPUT_DIR, 'pages.json'), JSON.stringify(publishedPages, null, 2));
|
|
// Extract category descriptions
|
|
const categoriesWithDescriptions = categories.map(cat => ({
|
|
id: cat.id,
|
|
name: cat.name,
|
|
slug: cat.slug,
|
|
description: cat.description || '',
|
|
count: cat.count || 0
|
|
}));
|
|
|
|
// Also save to wordpress directory
|
|
fs.writeFileSync(path.join(OUTPUT_DIR, 'categories.json'), JSON.stringify(categories, null, 2));
|
|
fs.writeFileSync(path.join(OUTPUT_DIR, 'tags.json'), JSON.stringify(tags, null, 2));
|
|
fs.writeFileSync(path.join(OUTPUT_DIR, 'authors.json'), JSON.stringify(authors, null, 2));
|
|
fs.writeFileSync(path.join(OUTPUT_DIR, 'author-posts.json'), JSON.stringify(authorPosts, null, 2));
|
|
fs.writeFileSync(path.join(OUTPUT_DIR, 'navigation.json'), JSON.stringify(navigationData, null, 2));
|
|
|
|
console.log(`✅ Fetched ${posts.length} posts, ${publishedPages.length} pages, ${categories.length} categories, ${tags.length} tags, ${authors.length} authors`);
|
|
console.log(`✅ Generated navigation data with ${navigationData.length} items`);
|
|
}
|
|
|
|
generateData().catch(console.error);
|