在我的Next.JS项目中,我在许多文件夹中分发了许多Markdown文件,这些文件夹被视为类别。因此,我在项目的根目录中有名为“CategoryOne”和“CategoryTwo”的文件夹(与node_modules、pages、public的级别相同)。这些文件夹中的每个都包含一些Markdown文件。
我有一个名为“ .md ”的页面,它应该呈现来自“CategoryOne”和“.md 2”的所有.md文件。正如我必须要得到的那样, As 是一个包含index.js (将所有.md文件作为文章列出)和slug.js (显示单击的文章)的文件夹。
让我们看一看!
pages/articles/index.js
import React, { useState } from 'react'
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import { useRouter } from 'next/router'
export default function Blog({ posts, postsTwo }) {
const router = useRouter()
if (router.isFallback) {
return <div>Loading...</div>
}
return (
<>
{/* Maps articles from both Categories */}
</>
)
}
export async function getStaticProps() {
const files = fs.readdirSync(path.join('CategoryOne'))
const posts = files.map((filename) => {
const slug = filename.replace('.md', '')
const markdownWithMeta = fs.readFileSync(
path.join('CategoryOne', filename),
'utf-8'
)
const { data: frontmatter } = matter(markdownWithMeta)
return {
slug,
frontmatter,
}
})
const files2 = fs.readdirSync(path.join('CategoryTwo'))
const posts2 = files2.map((filename) => {
const slug2 = filename.replace('.md', '')
const markdownWithMeta2 = fs.readFileSync(
path.join('CategoryTwo', filename),
'utf-8'
)
const { data: frontmatter } = matter(markdownWithMeta2)
return {
slug2,
frontmatter,
}
})
return {
props: {
posts: posts,
postsTwo: posts2,
},
}
}[slug].js
import React, { useState, useEffect } from 'react'
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import marked from 'marked'
import { useRouter } from 'next/router'
export default function PostPage({
frontmatter: { title, date, reading_time, category },
slug,
content,
posts,
}) {
if (router.isFallback) {
return <div>Loading...</div>
}
return (
<>
<div>
<h1>{title}</h1>
<p>{date} • {reading_time}</p>
<div>
<div dangerouslySetInnerHTML={{__html: marked(content)}}></div>
</div>
</div>
</>
)
}
export async function getStaticPaths() {
const files = fs.readdirSync(path.join('CategoryOne'))
const paths = files.map((filename) => ({
params: {
slug: filename.replace('.md', ''),
},
}))
return {
paths,
fallback: false,
}
}
export async function getStaticProps({ params: { slug } }) {
const files = fs.readdirSync(path.join('CategoryOne'))
const markdownWithMeta = fs.readFileSync(
path.join('CategoryOne', slug + '.md'),
'utf-8'
)
const { data: frontmatter, content } = matter(markdownWithMeta)
const posts = files.map((filename) => {
const slug = filename.replace('.md', '')
const markdownWithMeta = fs.readFileSync(
path.join('CategoryOne', filename),
'utf-8'
)
const { data: frontmatter } = matter(markdownWithMeta)
return {
slug,
frontmatter,
}
})
return {
props: {
frontmatter,
slug,
content,
posts,
},
}
}当我点击“CategoryTwo”中的一篇文章时,我得到了一个404错误。这是因为在slug.js中,我只能返回“类别一”中的段塞。
在index.js中,getStaticProps()太长了,我希望得到这个函数递归。因为我认为将类别文件夹放入一个名为“post”的文件夹会更好。因此,如果有更多的类别,我可以让所有的.md文件白化,用它们的名字称呼它们。
/posts
|______ /CategoryOne
|______ /CategoryTwo总之,我们必须将重点放在getStaticProps()、getStaticPaths()和文件系统libray上,以便递归地从子目录中列出文件。
2021] [编辑·9月10日]
我在我的utils/index.js中做了两个函数。第一个是子文件夹,第二个是每个子文件夹。
import { readdir } from 'fs/promises';
const postsDirectory = path.join(process.cwd(), 'posts');
export function getDirectories(postsDirectory) {
return fs
.readdirSync(postsDirectory, { withFileTypes: true })
.filter((dirent) => dirent.isDirectory())
.map((dirent) => dirent.name);
}
export async function getAllFiles() {
const test = getDirectories(postsDirectory);
let table = [];
for (const folder of test) {
const subfolder = path.join(postsDirectory, folder);
let files = await readdir(subfolder);
for (const file of files) {
table.push({ file: file, folder: folder });
}
}
return table;
}
/* Result
[
{ file: 'markdown-one-1.md', folder: 'CategoryOne' },
{ file: 'markdown-one-2.md', folder: 'CategoryOne' },
{ file: 'markdown-one-1.md', folder: 'CategoryTwo' },
{ file: 'markdown-one-2.md', folder: 'CategoryTwo' },
]
*/我发现,如果在posts文件夹中有一些子文件夹,那么在posts页面中应该有与下面的模式相同的内容:
├── node_modules
├── package.json
├── pages
│ ├── index.js
│ ├── _app.js
│ └── posts
│ ├── CategoryOne
│ ├── [id].js //to display .md files of CategoryOne
│ ├── CategoryTwo
│ ├── [id].js //to display .md files of CategoryTwo
├── ..
└── posts
├── CategoryOne
│ ├── markdown-one-1.md
│ ├── markdown-one-2.md
│ ├── markdown-one-3.md
│ └── ..
└── CategoryTwo
├── markdown-two-1.md
├── markdown-two-2.md
├── markdown-two-3.md
└── ..应该有一种方法来自动创建这些id.js文件,具体取决于您有多少子文件夹。
发布于 2021-09-09 21:08:35
就像您说的,最好将您的类别和它们的文章放在它们自己的目录中。我知道您提到过递归地这样做,但是如果这不是绝对的要求,我建议使用格罗布。
假设您有以下文件结构
├── node_modules
├── package.json
├── ..
└── posts
├── CategoryOne
│ ├── markdown-one-1.md
│ ├── markdown-one-2.md
│ ├── markdown-one-3.md
│ └── ..
└── CategoryTwo
├── markdown-two-1.md
├── markdown-two-2.md
├── markdown-two-3.md
└── ..然后,您可以在getStaticProps和/或getStaticPaths方法中执行类似的操作:
const glob = require('glob');
glob('posts/**/*.md', (err, files) => {
console.log({files});
/*
* will produce:
* {
* files: [
* 'posts/CategoryOne/markdown-one-1.md',
* 'posts/CategoryOne/markdown-one-2.md',
* 'posts/CategoryOne/markdown-one-3.md',
* 'posts/CategoryTwo/markdown-two-1.md',
* 'posts/CategoryTwo/markdown-two-2.md',
* 'posts/CategoryTwo/markdown-two-3.md'
* ]
* }
*/
});然后,您只需要对每个文件进行split('/'),组织类别/文件名,并将它们作为支持返回。
https://stackoverflow.com/questions/69122134
复制相似问题