16. next js _post에 .md파일 작성해서 저장하고 깃 커밋 푸시
2024-07-05
Author: 포리
pages/api/create-post.js
import fs from "fs";
import path from "path";
import { simpleGit } from "simple-git";
export default async function handler(req, res) {
if (req.method === "POST") {
const { title, author, keywords, content } = req.body;
const date = new Date().toISOString().split("T")[0];
// _posts 디렉터리의 파일 목록을 가져옴
const postsDir = path.join(process.cwd(), "_posts");
const files = fs.readdirSync(postsDir);
const postNumbers = files
.map((file) => parseInt(file.split(".")[0], 10))
.filter((num) => !isNaN(num));
const nextPostNumber = Math.max(0, ...postNumbers) + 1;
const nextFileName = `${nextPostNumber}. ${title.replace(/\s+/g, "-")}.md`;
const filePath = path.join(postsDir, nextFileName);
const fileContent = `---
title: "${nextPostNumber}. ${title}"
date: "${date}"
author: "${author}"
keywords: ${JSON.stringify(keywords)}
---
${content}
`;
try {
// 파일 작성
await fs.promises.writeFile(filePath, fileContent);
// Git 커밋 및 푸시
const git = simpleGit();
await git.add(filePath);
await git.commit(`Add new post: ${nextPostNumber}. ${title}`);
await git.push("origin", "main"); // 'main' 브랜치에 푸시
// 성공적으로 응답 전송
res
.status(200)
.json({
message: "Post created, committed, and pushed",
fileName: nextFileName,
});
} catch (err) {
// 오류 발생 시 응답 전송
res.status(500).json({ error: "Failed to create post" });
}
} else {
res.status(405).json({ error: "Method not allowed" });
}
}
pages/create-post.js
import { useState } from "react";
import styles from "../styles/CreatePost.module.css";
export default function CreatePost() {
const [title, setTitle] = useState("");
const [author, setAuthor] = useState("");
const [keywords, setKeywords] = useState("");
const [content, setContent] = useState("");
const [message, setMessage] = useState("");
const handleSubmit = async (e) => {
e.preventDefault();
const response = await fetch("/api/create-post", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title,
author,
keywords: keywords.split(","),
content,
}),
});
const data = await response.json();
if (response.ok) {
setMessage(`포스트가 생성되었습니다: ${data.fileName}`);
setTitle("");
setAuthor("");
setKeywords("");
setContent("");
} else {
setMessage(`오류: ${data.error}`);
}
};
return (
<div className={styles.container}>
<h1>새 글 작성하기</h1>
<form onSubmit={handleSubmit} className={styles.form}>
<div>
<label className={styles.label}>제목:</label>
<input
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
className={styles.input}
required
/>
</div>
<div>
<label className={styles.label}>작성자:</label>
<input
type="text"
value={author}
onChange={(e) => setAuthor(e.target.value)}
className={styles.input}
required
/>
</div>
<div>
<label className={styles.label}>키워드 (쉼표로 구분):</label>
<input
type="text"
value={keywords}
onChange={(e) => setKeywords(e.target.value)}
className={styles.input}
/>
</div>
<div>
<label className={styles.label}>내용:</label>
<textarea
value={content}
onChange={(e) => setContent(e.target.value)}
className={styles.textarea}
required
rows="10"
cols="50"
/>
</div>
<button type="submit" className={styles.button}>
글 작성
</button>
</form>
{message && <p>{message}</p>}
</div>
);
}