EJS를 사용한 마크다운 블로그
소개
HTML을 사용하여 게시물 내용을 작성하는 것은 Markdown을 사용하는 것만큼 쉽지 않습니다.
back to the roots whit a static site 오고 나서 Markdown으로 게시물 콘텐츠를 작성합니다.
그 후 얼마 지나지 않아 Deta Cloud을 발견했고 Node.js에 대해 배운 모든 것을 라이브 서버에서 사용해 볼 수 있었습니다.
내가 가장 좋아하는 템플릿 언어는 EJS 이며 Markdown 파일의 콘텐츠를 EJS 템플릿과 결합하여 아주 간단한 블로그를 만들고 싶었습니다.
많은 연구와 시도와 실패 끝에 목표를 달성하는 데 필요한 메커니즘을 이해했습니다.
이 주제에 대한 몇 가지 자습서를 찾았고 이 자습서는 내가 우연히 발견한 마지막 항목인 Building A Markdown Blog App with Express and EJS에서 영감을 받아 일부 개선 사항과 모든 세부 정보를 제공합니다.
요구 사항
마법 주문을 실행하려면 다음 패키지가 필요합니다.
Express , Node.js용 웹 프레임워크
gray-matter , Markdown 파일에서 머리말을 구문 분석하기 위해
markdown-it , Markdown 파일 내용을 구문 분석하기 위해
하나의 명령으로 설치하려면 다음을 수행하십시오.
npm i ejs express gray-matter markdown-it 서버 설정
메인 서버 파일에서 내 것은
index.js 입니다. 다음을 입력하십시오.// /index.js
const express = require("express")
const app = express()
// Built-in module to access and interact with the file system
const fs = require("fs")
// To parse front matter from Markdown files
const matter = require("gray-matter")
app.set("view engine", "ejs")
app.use(express.static("public"))
const getPosts = () => {
    // Get the posts from their directory
    const posts = fs.readdirSync(__dirname + "/views/posts").filter((post) => post.endsWith(".md"))
    // Set the post content as an empty array
    const postContent = []
    // Inject into the post content array the front matter
    posts.forEach((post) => {
        postContent.push(matter.read(__dirname + "/views/posts/" + post))
    })
    /**
     * 1- Return a list of posts as a two dimensional array containing for each one :
     * . the post filename with it's extension (e.g : postFilename.md)
     * . the post content as an object {content:"Markdown content as a string", data:{front matter}, excerpt:""}
     * 2- Return each array as an object and create a Date instance from it's date front matter
     * 3- Sort posts by publication's date in descending order (newest to oldest)
     */
    const postsList = posts
        .map(function (post, i) {
            return [post, postContent[i]]
        })
        .map((obj) => {
            return { ...obj, date: new Date(obj[1].data.date) }
        })
        .sort((objA, objB) => Number(objB.date) - Number(objA.date))
    return postsList
}
// Render the list of posts on the main route
app.get("/", (req, res) => {
    res.render("postsList", {
        posts: getPosts(),
    })
})
// Using a route parameter to render each post on a route matching it's filename
app.get("/posts/:post", (req, res) => {
    const postTitle = req.params.post // Get the Markdown filename
    // Read the Markdown file and parse it's front matter
    const post = matter.read(__dirname + "/views/posts/" + postTitle + ".md")
    // Convert the Markdown file content to HTML with markdown-it
    const md = require("markdown-it")({ html: true }) // Allows HTML tags inside the Markdown file
    const content = post.content // Read the Markdown file content
    const html = md.render(content) // Convert the Markdown file content to HTML
    // Render the postsTemplate for each post and pass it's front matter as a data object into postsTemplate
    res.render("postsTemplate", {
        title: post.data.title,
        date: post.data.date,
        postContent: html,
    })
})
// Launching the application on port 3000
app.listen(3000, () => {
    console.log(`App 🚀 @ http://localhost:3000`)
})
보시다시피 모든 것이 자세히 설명되어 있습니다.
참고: 저는 views 폴더를 템플릿 파일 위치로 직접 사용하고 있습니다. 선언할 필요가 없습니다. Express는 기본적으로 이를 감지하고 Markdown 파일은 posts라는 다른 폴더 내의 views 폴더 아래에 있습니다.
한 가지 특정한 점에 주의를 기울이고 싶습니다.
postTemplate를 렌더링하고 Markdown 머리말과 콘텐츠를 데이터 객체로 전달할 때 원하는 만큼 key: value 쌍을 추가하고 전달할 수 있지만 key 내부에서 정의되지 않은postTemplate을 호출할 수는 없습니다. ) !그래서 마크다운 파일의 머리말에
description: my post description를 추가하면 데이터 객체에 추가하지 않고는 postTemplate 내부에서 직접 호출할 수 없다.참고: 템플릿 파일의 확장자
.ejs를 선언할 필요가 없습니다. Express는 기본적으로 이를 감지합니다.프런트엔드 렌더링
index.js에서 본 것처럼 postsList.ejs라는 템플릿에서 기본 경로의 게시물 목록을 렌더링하고 있습니다. 이 파일에 다음을 추가합니다.<!-- /views/postsList.ejs -->
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Home | My blog</title>
    </head>
    <body>
        <h1>
            Welcome to my blog
            <br />
            List of recent posts
        </h1>
        <% posts.forEach(post => { %>
        <!-- Get the Markdown filename without it's extension -->
        <% const postFilename = post[0].replace(/\.[^/.]+$/, "") %>
        <!-- Get the Markdown post title from it's front matter -->
        <% const postTitle = post[1].data.title %>
        <!-- Render the title as a link to the post -->
        <h2><a href="/posts/<%= postFilename %>"><%= postTitle%></a></h2>
        <% }) %>
    </body>
</html>
이제 각 게시물은
postsTemplate.ejs라는 하나의 템플릿 파일이라는 동일한 구조를 가집니다. 여기에 다음을 추가합니다.<!-- /views/postsTemplate.ejs -->
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title><%= title %> | My blog</title>
    </head>
    <body>
        <h1><%= title %></h1>
        <p><%= date %></p>
        <div><%- postContent %></div>
    </body>
</html>
모든 것이 제자리에 있으므로 이제
views 폴더 아래의 posts 폴더에 Markdown을 사용하여 게시물을 작성할 수 있습니다 🥳시도하면 출력을 볼 수 있도록 두 개의 파일을 만들었습니다.
---
title: "My first article"
date: 2022/07/23
---
This is the content of my first article
<!--- /views/posts/my-first-article.md -->
---
title: "A second post"
date: 2022/07/25
---
Here goes the content of my second post
<!--- /views/posts/a-second-post.md -->
앱 구조는 다음 트리와 같습니다.
// App's structure without the node_modules folder
├── index.js
├── package-lock.json
├── package.json
└── views
  ├── posts
  │  ├── a-second-post.md
  │  └── my-first-article.md
  ├── postsList.ejs
  └── postsTemplate.ejs
이 튜토리얼이 EJS로 Markdown 블로그를 만들려는 모든 사람에게 도움이 되기를 바랍니다.
질문이 있으시면 주저하지 마십시오.
지금까지 읽어주셔서 감사합니다 💗
SYA,
레브시트
Reference
이 문제에 관하여(EJS를 사용한 마크다운 블로그), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/lebcit/markdown-blog-with-ejs-ogl텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)