58 lines
1.8 KiB
TypeScript
58 lines
1.8 KiB
TypeScript
import fs from 'fs';
|
|
import path from 'path';
|
|
import matter from 'gray-matter';
|
|
|
|
type PostData = { slug: string[]; frontmatter: Record<string, any> };
|
|
const CONTENT_DIR = path.join(process.cwd(), 'content');
|
|
|
|
export function getAllPosts(lang: string): PostData[] {
|
|
const dir = path.join(CONTENT_DIR, lang);
|
|
if (!fs.existsSync(dir)) return [];
|
|
return fs.readdirSync(dir)
|
|
.filter(f => f.endsWith('.md'))
|
|
.map(file => {
|
|
const full = path.join(dir, file);
|
|
const { data } = matter(fs.readFileSync(full, 'utf-8'));
|
|
const slug = file.replace(/\.md$/, '');
|
|
return { slug: [slug], frontmatter: data };
|
|
});
|
|
}
|
|
|
|
// ===== News (Markdown CMS) =====
|
|
export type NewsItem = {
|
|
slug: string;
|
|
title: string;
|
|
date: string;
|
|
summary?: string;
|
|
tags?: string[];
|
|
};
|
|
|
|
const NEWS_DIR = path.join(CONTENT_DIR, 'news');
|
|
|
|
export function getAllNews(): NewsItem[] {
|
|
if (!fs.existsSync(NEWS_DIR)) return [];
|
|
return fs
|
|
.readdirSync(NEWS_DIR)
|
|
.filter(f => f.endsWith('.md'))
|
|
.map(file => {
|
|
const full = path.join(NEWS_DIR, file);
|
|
const { data } = matter(fs.readFileSync(full, 'utf-8'));
|
|
const slug = file.replace(/\.md$/, '');
|
|
return {
|
|
slug,
|
|
title: String(data.title || slug),
|
|
date: String(data.date || ''),
|
|
summary: data.summary ? String(data.summary) : undefined,
|
|
tags: Array.isArray(data.tags) ? data.tags.map(String) : undefined,
|
|
} as NewsItem;
|
|
})
|
|
.sort((a, b) => (a.date < b.date ? 1 : -1));
|
|
}
|
|
|
|
export function getNewsBySlug(slug: string): { frontmatter: Record<string, any>; content: string } | null {
|
|
const filepath = path.join(NEWS_DIR, `${slug}.md`);
|
|
if (!fs.existsSync(filepath)) return null;
|
|
const raw = fs.readFileSync(filepath, 'utf-8');
|
|
const { data, content } = matter(raw);
|
|
return { frontmatter: data, content };
|
|
} |