使用 Node.Js、Express 和 EJS 在索引页面的不同部分显示博客文章

Posted

技术标签:

【中文标题】使用 Node.Js、Express 和 EJS 在索引页面的不同部分显示博客文章【英文标题】:Display blog posts on different sections on the index page with Node.Js, Express and EJS 【发布时间】:2018-09-08 17:52:50 【问题描述】:

我是 node.js 和一般编程的新手,所以这个问题对专家来说可能听起来很愚蠢,但我正在尝试构建一个简单的博客应用程序。我正在努力解决的部分是如何将数据呈现到我的视图中。我希望能够在索引页面的不同部分显示基于类别(体育、时尚、新闻等)的帖子,类似于 www.newyorker.com 这样的新闻网站在其主页上的内容。我使用 express、mongoose 和 ejs 作为我的视图引擎。

谢谢!

--------

This is my app.js file:

var bodyParser          = require("body-parser"),
    methodOverride      = require("method-override"),
    expressSanitizer    = require("express-sanitizer"),
    mongoose            = require("mongoose"),
    express             = require("express"),
    app                 = express();


// APP CONFIG
mongoose.connect("mongodb://localhost/tnm_blog_app");
app.set("view engine", "ejs");
app.use(express.static("public"));
app.use(bodyParser.urlencoded(extended: true));
app.use(expressSanitizer());
app.use(methodOverride("_method"));




// MONGOOSE/MODEL CONFIG

var blogSchema = new mongoose.Schema(
    title: String,
    image: String,
    body: String,
    category: String, 
    author: String, 
    created: type: Date, default: Date.now
);

var Blog = mongoose.model("Blog", blogSchema); 

// ROUTES

app.get("/", function(req, res)
    res.redirect("/index"); 
);

// INDEX ROUTE

app.get("/index", function(req, res)
    Blog.find(, function(err, blogs)
        if(err)
            console.log("ERROR!");
         else 
            res.render("index", blogs: blogs);
        
    );
);

// NEW ROUTE
app.get("/index/new", function(req, res)
    res.render("new");
);

// CREATE ROUTE

app.post("/index", function(req, res)
Blog.create(req.body.blog, function(err, newBlog)
    if(err)
        res.render("new");
     else 
        res.redirect("/index");
    
);
);


// SHOW ROUTE

app.get("/index/:id", function(req, res)

   Blog.findById(req.params.id, function(err, foundBlog)
       if(err)
           res.redirect("/index");
        else 
           res.render("show", blog: foundBlog);
       
   );
);

// EDIT ROUTE

app.get("/index/:id/edit", function(req, res)
    Blog.findById(req.params.id, function(err, foundBlog)
        if(err)
            res.redirect("/index");
         else 
            res.render("edit", blog: foundBlog);
        
    );
);

// UPDATE ROUTE

app.put("/index/:id", function(req, res)
    req.body.blog.body = req.sanitize(req.body.blog.body);
    Blog.findByIdAndUpdate(req.params.id, req.body.blog, function(err, updatedBlog)
      if(err)
          res.redirect("/index");
        else 
          res.redirect("/index/" + req.params.id);
      
    );
);

// DELETE ROUTE
app.delete("/index/:id", function(req, res)
    Blog.findByIdAndRemove(req.params.id, function(err)
        if(err)
            res.redirect("/index");
         else 
            res.redirect("/index");
        
    );
);


app.listen(3000, function()
    console.log("SERVER IS RUNNING!");
);

This is my index.ejs file
------------------------
<% include ./partials/header %>

<div class="ui main text container">
    <div class="ui huge header">The TNM Blog</div>
    <div class="ui top  attached segment">
        <div class="ui divided items">
            <% blogs.forEach(function(blog) %>
                <div class="item">
                    <div class="image">
                        <img src="<%= blog.image %>" >
                    </div>
                    <div class="content">
                         <a class="header" href="/blogs/<%= blog._id %>"><%=blog.title%></a>
                         <div class="meta">
                             <span><%= blog.created.toDateString() %></span>
                         </div>
                         <div class="description">
                             <p><%- blog.body.substring(0, 100) %>...</p>
                         </div>
                         <div class="extra">
                             <a class="ui floated basic violet button" href="/index/<%= blog._id %>">
                                 Read More
                                 <i class="right chevron icon"></i>
                             </a>
                         </div>
                    </div>
                </div>
            <% ) %>
        </div>
    </div>
</div>

<% include ./partials/footer %>

This is my show template

<% include ./partials/header %>
<div class="ui main text container segment">
    <div class="ui huge header"><%= blog.title %></div>
    <div class="ui top attached ">
        <div class="item">
            <img class="ui centered rounded image" src="<%= blog.image %>" >
            <div class="content">
                <span><%= blog.created.toDateString() %></span>
            </div>
            <div class="description">
                <p><%- blog.body %></p>
            </div>
            <a class="ui orange basic button" href="/index/<%= blog._id %>/edit">Edit</a>
            <form id="delete" action="/index/<%= blog._id %>?_method=DELETE" method="POST">
                <button class="ui red basic button">Delete</button>
            </form>
        </div>
    </div>

</div>
<% include ./partials/footer %>

【问题讨论】:

【参考方案1】:

您需要告诉渲染引擎帖子需要过滤到哪些类别,然后根据每个类别将不同的 forEach 循环放入 ejs 模板中。我相信您可以以更聪明的方式提取类别,但我只是在这里硬编码一个字符串数组:

// INDEX ROUTE

app.get("/index", function(req, res)
    Blog.find(, function(err, blogs)
        if(err)
            console.log("ERROR!");
         else 
            var categories = ['news', 'shopping']
            res.render("index", blogs: blogs, categories: categories);
        
    );
);

然后在您的 ejs 模板中,您可以创建一个 forEach 类别,然后显示符合该类别的博客

<% categories.forEach(function(category) %>
    <% blogs.forEach(function(blog) %>
        <% if(blog.category == category)  %>
        <div class="item">
            <div class="image">
                <img src="<%= blog.image %>" >
            </div>
            <div class="content">
                <a class="header" href="/blogs/<%= blog._id %>"><%=blog.title%></a>
                <div class="meta">
                    <span><%= blog.created.toDateString() %></span>
                </div>
                <div class="description">
                    <p><%- blog.body.substring(0, 100) %>...</p>
                </div>
                <div class="extra">
                    <a class="ui floated basic violet button" href="/index/<%= blog._id %>">
                        Read More
                        <i class="right chevron icon"></i>
                    </a>
                </div>
            </div>
        </div>
        <%  %>
    <% ) %>
<% ) %>

上面的肯定可以,但是效率有点低,所以我也鼓励你尝试看看ejs是否支持JS过滤功能

<% blogs.filter(b => b.category==category).forEach(function(blog) %>

【讨论】:

以上是关于使用 Node.Js、Express 和 EJS 在索引页面的不同部分显示博客文章的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 mongodb、node.js、express 和 EJS 创建动态站点地图?

Node JS+Express:如何在 HTML(EJS) 中定义和使用 MySQL 数据?

使用 Node.Js、Express 和 EJS 在索引页面的不同部分显示博客文章

在Javascript(node.js,express.js,ejs)中访问服务器端变量[关闭]

无法让样式表与 node.js 的 ejs 一起使用

如何在 Node.js 和 Express 上的同一个 .ejs 文件上呈现 MySQL 查询的多个结果?