Files
fad-trade-next/lib/getBlogs.ts

66 lines
1.8 KiB
TypeScript
Raw Normal View History

2025-11-21 13:36:06 +08:00
import { DEFAULT_LOCALE } from '@/i18n/routing';
import { BlogPost } from '@/types/blog';
import fs from 'fs';
import matter from 'gray-matter';
import path from 'path';
2025-11-21 13:36:06 +08:00
const POSTS_BATCH_SIZE = 10;
export async function getPosts(locale: string = DEFAULT_LOCALE): Promise<{ posts: BlogPost[] }> {
const postsDirectory = path.join(process.cwd(), 'blogs', locale);
// is directory exist
if (!fs.existsSync(postsDirectory)) {
return { posts: [] };
}
let filenames = await fs.promises.readdir(postsDirectory);
filenames = filenames.reverse();
2025-11-21 13:36:06 +08:00
let allPosts: BlogPost[] = [];
2025-11-21 13:36:06 +08:00
// read file by batch
for (let i = 0; i < filenames.length; i += POSTS_BATCH_SIZE) {
const batchFilenames = filenames.slice(i, i + POSTS_BATCH_SIZE);
const batchPosts: BlogPost[] = await Promise.all(
batchFilenames.map(async (filename) => {
const fullPath = path.join(postsDirectory, filename);
const fileContents = await fs.promises.readFile(fullPath, 'utf8');
const { data, content } = matter(fileContents);
return {
locale, // use locale parameter
title: data.title,
description: data.description,
image: data.image || '',
slug: data.slug,
tags: data.tags,
date: data.date,
visible: data.visible || 'published',
pin: data.pin || false,
content,
metadata: data,
};
})
);
allPosts.push(...batchPosts);
}
2025-11-21 13:36:06 +08:00
// filter out non-published articles
allPosts = allPosts.filter(post => post.visible === 'published');
2025-11-21 13:36:06 +08:00
// sort posts by pin and date
allPosts = allPosts.sort((a, b) => {
if (a.pin !== b.pin) {
return (b.pin ? 1 : 0) - (a.pin ? 1 : 0);
}
return new Date(b.date).getTime() - new Date(a.date).getTime();
});
2025-11-21 13:36:06 +08:00
return {
posts: allPosts,
2025-11-21 13:36:06 +08:00
};
}