|
@@ -145,12 +145,14 @@ function parsePostMetadata(content) {
|
|
|
const descMatch = content.match(/desc:\s*(.*)/);
|
|
const descMatch = content.match(/desc:\s*(.*)/);
|
|
|
const tagsMatch = content.match(/tags:\s*(.*)/);
|
|
const tagsMatch = content.match(/tags:\s*(.*)/);
|
|
|
const hiddenMatch = content.match(/hidden:\s*(true|false)/);
|
|
const hiddenMatch = content.match(/hidden:\s*(true|false)/);
|
|
|
|
|
+ const pinnedMatch = content.match(/pinned:\s*(true|false)/);
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
|
title: titleMatch ? titleMatch[1].trim() : "Untitled",
|
|
title: titleMatch ? titleMatch[1].trim() : "Untitled",
|
|
|
description: descMatch ? descMatch[1].trim() : "",
|
|
description: descMatch ? descMatch[1].trim() : "",
|
|
|
tags: tagsMatch ? tagsMatch[1].split(",").map((tag) => tag.trim()) : [],
|
|
tags: tagsMatch ? tagsMatch[1].split(",").map((tag) => tag.trim()) : [],
|
|
|
hidden: hiddenMatch ? hiddenMatch[1] === "true" : false,
|
|
hidden: hiddenMatch ? hiddenMatch[1] === "true" : false,
|
|
|
|
|
+ pinned: pinnedMatch ? pinnedMatch[1] === "true" : false,
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -445,8 +447,12 @@ app.get("/api/posts", async (req, res) => {
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Sort by creation date, newest first
|
|
|
|
|
- posts.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
|
|
|
|
|
|
|
+ // Sort by pinned (true first), then by creation date (newest first)
|
|
|
|
|
+ posts.sort((a, b) => {
|
|
|
|
|
+ if (a.pinned && !b.pinned) return -1;
|
|
|
|
|
+ if (!a.pinned && b.pinned) return 1;
|
|
|
|
|
+ return new Date(b.createdAt) - new Date(a.createdAt);
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
// Filter out hidden posts for non-admins
|
|
// Filter out hidden posts for non-admins
|
|
|
const isAdmin = req.session && req.session.user && req.session.user.role === "admin";
|
|
const isAdmin = req.session && req.session.user && req.session.user.role === "admin";
|
|
@@ -499,7 +505,7 @@ app.get("/api/posts/:slug", async (req, res) => {
|
|
|
// POST /api/posts - Create new post
|
|
// POST /api/posts - Create new post
|
|
|
app.post("/api/posts", requireAuth, async (req, res) => {
|
|
app.post("/api/posts", requireAuth, async (req, res) => {
|
|
|
try {
|
|
try {
|
|
|
- const { title, description, content, tags, hidden } = req.body;
|
|
|
|
|
|
|
+ const { title, description, content, tags, hidden, pinned } = req.body;
|
|
|
|
|
|
|
|
if (!title || !content) {
|
|
if (!title || !content) {
|
|
|
return res
|
|
return res
|
|
@@ -525,6 +531,7 @@ app.post("/api/posts", requireAuth, async (req, res) => {
|
|
|
if (tags && tags.length > 0)
|
|
if (tags && tags.length > 0)
|
|
|
postContent += `tags: ${tags.join(", ")}\n`;
|
|
postContent += `tags: ${tags.join(", ")}\n`;
|
|
|
if (hidden) postContent += `hidden: true\n`;
|
|
if (hidden) postContent += `hidden: true\n`;
|
|
|
|
|
+ if (pinned) postContent += `pinned: true\n`;
|
|
|
postContent += "\n" + content;
|
|
postContent += "\n" + content;
|
|
|
|
|
|
|
|
// Write the file
|
|
// Write the file
|
|
@@ -556,7 +563,7 @@ app.post("/api/posts", requireAuth, async (req, res) => {
|
|
|
app.put("/api/posts/:slug", requireAuth, async (req, res) => {
|
|
app.put("/api/posts/:slug", requireAuth, async (req, res) => {
|
|
|
try {
|
|
try {
|
|
|
const { slug } = req.params;
|
|
const { slug } = req.params;
|
|
|
- const { title, description, content, tags, hidden } = req.body;
|
|
|
|
|
|
|
+ const { title, description, content, tags, hidden, pinned } = req.body;
|
|
|
|
|
|
|
|
const oldFilename = `${slug}.md`;
|
|
const oldFilename = `${slug}.md`;
|
|
|
const oldFilePath = path.join(POSTS_DIR, oldFilename);
|
|
const oldFilePath = path.join(POSTS_DIR, oldFilename);
|
|
@@ -588,6 +595,7 @@ app.put("/api/posts/:slug", requireAuth, async (req, res) => {
|
|
|
if (tags && tags.length > 0)
|
|
if (tags && tags.length > 0)
|
|
|
postContent += `tags: ${tags.join(", ")}\n`;
|
|
postContent += `tags: ${tags.join(", ")}\n`;
|
|
|
if (hidden) postContent += `hidden: true\n`;
|
|
if (hidden) postContent += `hidden: true\n`;
|
|
|
|
|
+ if (pinned) postContent += `pinned: true\n`;
|
|
|
postContent += "\n" + content;
|
|
postContent += "\n" + content;
|
|
|
|
|
|
|
|
// Write to new file
|
|
// Write to new file
|