almost done
This commit is contained in:
111
lib/posts.ts
Normal file
111
lib/posts.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import matter from "gray-matter";
|
||||
|
||||
const postsDirectory = path.join(process.cwd(), "content");
|
||||
const tagsFilePath = path.join(postsDirectory, "tags.json");
|
||||
|
||||
type PostData = {
|
||||
id: string;
|
||||
href: string;
|
||||
date: string;
|
||||
tags: string[];
|
||||
image: string | null;
|
||||
title?: string;
|
||||
excerpt?: string;
|
||||
video?: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
function getPostFilePaths(dir: string, fileList: string[] = []) {
|
||||
const files = fs.readdirSync(dir);
|
||||
|
||||
files.forEach((file) => {
|
||||
const filePath = path.join(dir, file);
|
||||
if (fs.statSync(filePath).isDirectory()) {
|
||||
getPostFilePaths(filePath, fileList);
|
||||
} else if (filePath.endsWith(".mdx")) {
|
||||
fileList.push(filePath);
|
||||
}
|
||||
});
|
||||
|
||||
return fileList;
|
||||
}
|
||||
|
||||
export function getSortedPostsData(category?: string): PostData[] {
|
||||
const directory = category ? path.join(postsDirectory, category) : postsDirectory;
|
||||
const filePaths = getPostFilePaths(directory);
|
||||
|
||||
const allPostsData = filePaths.map((filePath) => {
|
||||
const id = path.basename(filePath).replace(/\.mdx$/, "").replace(/^\d{4}-\d{2}-\d{2}-/, '');
|
||||
const relativePath = path.relative(postsDirectory, filePath).replace(/\.mdx$/, "");
|
||||
const pathParts = relativePath.split(path.sep);
|
||||
pathParts.pop(); // remove the old filename
|
||||
pathParts.push(id);
|
||||
const href = pathParts.join('/'); // use forward slashes for URLs
|
||||
|
||||
const fileContents = fs.readFileSync(filePath, "utf8");
|
||||
const matterResult = matter(fileContents);
|
||||
|
||||
const dateFromFileName = path.basename(filePath).substring(0, 10);
|
||||
|
||||
const tags = matterResult.data.tags
|
||||
? Array.isArray(matterResult.data.tags)
|
||||
? matterResult.data.tags
|
||||
: matterResult.data.tags.split(/, ?/)
|
||||
: [];
|
||||
|
||||
let image = matterResult.data.teaser || matterResult.data.image || null;
|
||||
|
||||
return {
|
||||
id,
|
||||
href,
|
||||
date: matterResult.data.date ?? dateFromFileName,
|
||||
...matterResult.data,
|
||||
tags,
|
||||
image,
|
||||
};
|
||||
});
|
||||
|
||||
return allPostsData.sort((a, b) => {
|
||||
if (!a.date || a.date < b.date) {
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function getAllTags(minCount: number = 1) {
|
||||
const allPosts = getSortedPostsData();
|
||||
const tags: { [tag: string]: number } = {};
|
||||
|
||||
allPosts.forEach((post) => {
|
||||
post.tags.forEach((tag: string) => {
|
||||
if (tag in tags) {
|
||||
tags[tag]++;
|
||||
} else {
|
||||
tags[tag] = 1;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return Object.entries(tags)
|
||||
.map(([name, count]) => ({ name, count }))
|
||||
.filter(tag => tag.count >= minCount);
|
||||
}
|
||||
|
||||
export function getPostsByTag(tag: string) {
|
||||
const allPosts = getSortedPostsData();
|
||||
return allPosts.filter((post) => post.tags.includes(tag));
|
||||
}
|
||||
|
||||
export function getTagData(tag: string) {
|
||||
if (!fs.existsSync(tagsFilePath)) {
|
||||
return null;
|
||||
}
|
||||
const tagsFile = fs.readFileSync(tagsFilePath, "utf8");
|
||||
const tagsData = JSON.parse(tagsFile);
|
||||
return tagsData[tag] || null;
|
||||
}
|
||||
Reference in New Issue
Block a user