diff --git a/scripts/fetch-wordpress.js b/scripts/fetch-wordpress.js
index 290e176..13dfd93 100644
--- a/scripts/fetch-wordpress.js
+++ b/scripts/fetch-wordpress.js
@@ -4,32 +4,32 @@ const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch
const WORDPRESS_API = 'https://www.mistergeek.net/wp-json/wp/v2';
const OUTPUT_DIR = path.join(__dirname, '..', 'data', 'wordpress');
+const HUGO_DATA_DIR = path.join(__dirname, '..', 'data');
-async function fetchPosts(page = 1, perPage = 100) {
- const response = await fetch(`${WORDPRESS_API}/posts?page=${page}&per_page=${perPage}&_embed`);
- const posts = await response.json();
-
- if (response.headers.get('x-wp-totalpages') > page) {
- const nextPosts = await fetchPosts(page + 1, perPage);
- return [...posts, ...nextPosts];
+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 posts;
-}
-async function fetchCategories() {
- const response = await fetch(`${WORDPRESS_API}/categories?per_page=100`);
- return response.json();
-}
-
-async function fetchTags() {
- const response = await fetch(`${WORDPRESS_API}/tags?per_page=100`);
- return response.json();
-}
-
-async function fetchAuthors() {
- const response = await fetch(`${WORDPRESS_API}/users?per_page=100`);
- return response.json();
+ return items;
}
async function generateData() {
@@ -39,21 +39,45 @@ async function generateData() {
}
console.log('Fetching WordPress data...');
-
- const [posts, categories, tags, authors] = await Promise.all([
- fetchPosts(),
- fetchCategories(),
- fetchTags(),
- fetchAuthors()
+
+ // 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
+ }));
+
// 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));
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, 'navigation.json'), JSON.stringify(navigationData, null, 2));
- console.log(`✅ Fetched ${posts.length} posts, ${categories.length} categories, ${tags.length} tags, ${authors.length} authors`);
+ 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);
\ No newline at end of file
diff --git a/scripts/generate-content.js b/scripts/generate-content.js
index f07af8c..aa48178 100644
--- a/scripts/generate-content.js
+++ b/scripts/generate-content.js
@@ -4,15 +4,22 @@ const he = require('he');
const DATA_DIR = path.join(__dirname, '..', 'data', 'wordpress');
const CONTENT_DIR = path.join(__dirname, '..', 'content');
+const PAGES_DIR = path.join(CONTENT_DIR, 'pages');
function generateContent() {
const posts = JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'posts.json'), 'utf8'));
-
- // Ensure content directory exists
+ const pages = JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'pages.json'), 'utf8'));
+
+ // Ensure content directories exist
if (!fs.existsSync(CONTENT_DIR)) {
fs.mkdirSync(CONTENT_DIR, { recursive: true });
}
+
+ if (!fs.existsSync(PAGES_DIR)) {
+ fs.mkdirSync(PAGES_DIR, { recursive: true });
+ }
+ // Process posts
posts.forEach(post => {
const slug = post.slug;
const date = new Date(post.date);
@@ -61,7 +68,58 @@ function generateContent() {
contentHtml = contentHtml
.replace(/\s*<\/p>/g, '') // Remove empty paragraphs
- .replace(/<\/p>\s*
/g, '\n\n') // Replace paragraph breaks with newlines
+ .replace(/<\/p>\s*
/g, '\n\n'); // Replace paragraph breaks with newlines
+
+ const content = `---
+${Object.entries(frontmatter)
+ .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)
+ .join('\n')}
+---
+${contentHtml.trim()}`;
+
+ fs.writeFileSync(path.join(contentDir, 'index.md'), content);
+ });
+
+ // Process pages
+ pages.forEach(page => {
+ const slug = page.slug;
+
+ const contentDir = path.join(PAGES_DIR, slug);
+
+ if (!fs.existsSync(contentDir)) {
+ fs.mkdirSync(contentDir, { recursive: true });
+ }
+
+ const frontmatter = {
+ title: he.decode(page.title.rendered),
+ slug: slug,
+ type: "pages",
+ layout: "single",
+ wordpress_id: page.id,
+ date: page.date,
+ modified: page.modified,
+ draft: page.status !== 'publish',
+ aliases: [`/${slug}/`]
+ };
+
+ // Decode HTML entities in the content and clean up HTML tags
+ let contentHtml = he.decode(page.content.rendered);
+
+ // Convert absolute URLs in a href to relative URLs
+ contentHtml = contentHtml.replace(/]*href="([^"]+)"[^>]*>/g, (match, href) => {
+ // Check if the href is an absolute URL (starts with http:// or https://)
+ if (href.startsWith('http://') || href.startsWith('https://')) {
+ // Extract the path part of the URL
+ const url = new URL(href);
+ // Return the modified a tag with relative URL
+ return match.replace(href, url.pathname);
+ }
+ return match;
+ });
+
+ contentHtml = contentHtml
+ .replace(/\s*<\/p>/g, '') // Remove empty paragraphs
+ .replace(/<\/p>\s*
/g, '\n\n'); // Replace paragraph breaks with newlines
const content = `---
${Object.entries(frontmatter)
@@ -74,6 +132,7 @@ ${contentHtml.trim()}`;
});
console.log(`✅ Generated ${posts.length} content files`);
+ console.log(`✅ Generated ${pages.length} page files`);
}
generateContent();
\ No newline at end of file