问题通过 express 动态呈现路线

问题描述 投票:0回答:0

我正在构建一个使用 Node、ejs、express、markdown-it 和 gray-matter 的博客。基本功能是这样的:md 文件存储在 /posts 中。当博客加载时,它会呈现当前所有的博客文章。它使用灰质来解析每个 md 文件的 front matter,从而使我们能够访问该帖子的主题。在每个页面的顶部是通过单击主题标签来过滤帖子的方法。然后将这些过滤后的结果传递给视图引擎,然后呈现适当的帖子。

项目目录如下所示(node_modules 也在那里,但为了清楚起见省略了:

    .
├── index.js
├── package.json
├── package-lock.json
├── posts
│   ├── first-post.md
│   └── second-post.md
├── public
│   ├── images
│   ├── styles.css
│   ├── styles.css.map
│   └── styles.scss
├── README.md
├── router.js
└── views
    ├── filtered-posts.ejs
    ├── index.ejs
    └── partials
        ├── footer.ejs
        ├── head.ejs
        ├── header.ejs
        ├── page-content.ejs
        └── topics.ejs

问题:单击其中一个主题标签后,我继续收到错误消息:

无法获取/posts/javascript.html

这让我觉得我生成的链接有问题,或者我的路由器中缺少一块。我的文件看起来像这样:

// index.js
const express = require('express')
const app = express()
const router = require('./router')

app.set('view engine', 'ejs')
// set the public dir to static
app.use(express.static('public'))
app.use('/posts', router)
// defines a route for the homepage that displays all the blog posts on load
app.get('/', (req, res) => {
  res.redirect('/posts')
})


app.listen(3000, () => {
  console.log('server running on port 3000')
})

// router.js

const express = require('express')
const router = express.Router()
const fs = require('fs')
const matter = require('gray-matter')
const MarkdownIt = require('markdown-it')

router.get('/', (req, res) => {
  const topics = []
  const posts = []

  fs.readdirSync('posts').forEach(file => {
    // extract file content for ea file in posts directory, convert md to a js obj to work w/ using GM and then convert the 'content' property value to html (originally from md file) 
    const fileContent = fs.readFileSync('posts/' + file, 'utf8')
    const { data, content } = matter(fileContent)
    const html = MarkdownIt().render(content)
    const formattedDate = new Date(data.date).toLocaleDateString('en-US');

    posts.push({
      title: data.title,
      date: formattedDate,
      topic: data.topic,
      content: html
    })
    
    if (data.topic && !topics.includes(data.topic)) {
      topics.push(data.topic)
    }
  });

  // generate routes dynamically based on the topics included in the arr 
  topics.forEach(topic => {
    router.get(`/posts/${topic}`, (req, res) => {
      // holds the posts that share the topic both in the arr and in our md
      const filteredPosts = posts.filter(post => post.topic == topic)
      res.render('filtered-posts', {posts: filteredPosts, topics})
    })
  })

  res.render('index', {posts, topics})

})

module.exports = router

// topics.ejs (this is where the topic tag href is set)

<section class="topics">
  <ul class="topics-list">
    <% topics.forEach(topic => { %>
      <li class="topic-list-item"> <a href="/posts/<%= topic %>.html" class="topic-list-link"> <%= topic %> </a> </li>
    <% }) %>
  </ul>
</section>

感谢您的时间和精力。

将主题标签的 href 链接从

更改为
  "posts/<%= topic %>.html"

以下内容:

  "/posts/<%= topic %>.html"
  • 仔细检查我是否正确导入路由器并将其设置为中间件
  • 创建了一个 filtered-posts.ejs(实际上只是 index.ejs 的副本)这里的思考过程可能是当我将数据传递到视图时它没有工作,因为我将它传递到当前正在使用的相同视图渲染。
  • 将 router.ejs 从路由目录移动到存储在根目录下的单个 router.ejs 文件。这里的思考过程是,也许我从 router.ejs 到它需要的位置的路径导致了错误,即无效的文件路径
  • 检查服务器是否正常运行
  • 检查以确保主题的动态路由使用正确的方法 (GET)

我原以为在单击主题标签后我会被移动到 /posts/topic/ 并且这样做会呈现包含我刚刚单击的主题标签的所有帖子。

javascript html express ejs
© www.soinside.com 2019 - 2024. All rights reserved.