nodejs--express开发博客系统(三)

    上一节已经实现了登陆、注册、发表文章和文章读取的功能,今天咱加上评论、文章页面和做者页面。javascript

     评论只能在进入文章页面后才能进行,因此我们先写文章页面。css

     在上一节的代码中,我已经给文章标题添加了超连接了,html

<a href="/<%= post.user %>/<%= post.time.day%>/<%= post.title %>"><%= post.title %></a>

     根据这个连接地址,进入文章页面的路由控制就能够写成这样:java

 

 

app.get('/:user/:time/:title', function(req,res){
    User.get(req.params.user,function(err, user){
        Post.getOne(req.params.user, req.params.time, req.params.title, function(err, post){//还记得post.js里面获取文章的函数吧?
            if(err){
                req.flash('err',err); 
                return res.redirect('/');
            }
            res.render('article',{
                title: req.params.title,
                post: post,
                user: req.session.user,
                success: req.flash('success').toString(),
                error: req.flash('error').toString()
            });
        });
    });
});

    接下来写文章页面的视图 article.ejsweb

<%- include header %>
<p><h2><a href="/<%= locals.post.user %>/<%= locals.post.time.day %>/<%= locals.post.title %>"><%= locals.post.title %></a></h2></p>
<p class="info">
    做者:<a href="/<%= locals.post.user %>"><%= locals.post.user %></a> |
    日期:<%= locals.post.time.minute %> 
</p>
<p><%- locals.post.post %></p>
<p class="info">阅读:<%= locals.post.pv %> | 评论:<%= locals.post.comments.length %>
<%- include footer %>

进入主页点击文章标题看看效果吧?正则表达式

 


         发现问题了吧?样式都没有了,缘由先不说,说完解决方法以后你就明白了:数据库

        把header.ejs中引入style.css的路径写成这样:session

<link rel="stylesheet" href="/stylesheets/style.css">

      好了,ok了!数据结构

 

     如今在文章页面后面加上评论,完整的article.ejs为:app

 

<%- include header %>
<p><h2><a href="/<%= locals.post.user %>/<%= locals.post.time.day %>/<%= locals.post.title %>"><%= locals.post.title %></a></h2></p>
<p class="info">
    做者:<a href="/<%= locals.post.user %>"><%= locals.post.user %></a> |
    日期:<%= locals.post.time.minute %> 
</p>
<p><%- locals.post.post %></p>
<p class="info">阅读:<%= locals.post.pv %> | 评论:<%= locals.post.comments.length %>

<br /><br />
<% if(locals.post.comments){ %>
<% locals.post.comments.forEach(function(comment, index){ %>
    <p><a href="/<%= comment.website %>"><%= comment.name %></a>
    <time>回复于 <%= comment.time %></time></p>
    <p><%- comment.content %></p>
<% }) %>
<% } %>


<form method="post">
<% if(!locals.user){ %>
姓名:<input type="text" name="name" /><br />
邮箱:<input type="text" name="email" /><br />
网址:<input type="text" name="website" /><br />
<% } %>
留言:<br /><textarea name="content" rows="5" cols="80"></textarea>
      <br /><input type="submit" value="留言" />
</form>
<%- include footer %>

      评论视图有了,下面就是处理过程了,在app.get("/:user/:time/:title",function(){})后面添加:

 

 

app.post('/:user/:time/:title', function(req,res){
    var comment = null,
        date = new Date(),
        time = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes();
    if(req.session.user){
        var name=req.session.user.name;
        comment = {"name":name, "email":name+"@gmail.com", "website":"www."+name+".com", "time":time, "content":req.body.content}
    } else {
        comment = {"name":req.body.name, "email":req.body.email, "website":req.body.website, "time":time, "content":req.body.content}
    }
    var oneComment = new Comment(req.params.user, req.params.time, req.params.title, comment);
    oneComment.save(function(err){
        if(err){
            req.flash('error', err); 
            return res.redirect('/');
        }
        req.flash('success', '评论成功!');
        res.redirect('back');//这句话的做用是评论成功后返回到被评论文章
    });
});

      做者页面和文章页面是相似的,点击做者名字,显示该做者的全部文章。

 

       做者页面路由控制:

 

app.get('/:user', function(req,res){
        User.get(req.params.user, function(err, user){
        if(!user){
            return res.redirect('/');
        }

        Post.getAll(req.params.user, function(err, posts){
            if(err){
                req.flash('err',err); 
                return res.redirect('/');
            } 
            res.render('user',{
                title: req.params.user,
                posts: posts,
                user: req.session.user,
                success: req.flash('success').toString(),
                error: req.flash('error').toString()
            });
        });
    }); 
});

       做者页面视图user.ejs:

 

 

<%- include header %>
<% locals.posts.forEach(function(post, index){ %>
    <p><h2><a href="/<%=post.user %>/<%=post.time.day %>/<%=post.title %>"><%= post.title %></a></h2>
     <p class="info">
        做者:<a href="/<%= post.user %>"><%= post.user %></a> |
        日期:<%= post.time.minute %>
    </p>
    <p><%- post.post %></p>
    <p class="info">阅读:<%= post.pv %> | 评论:<%= post.comments.length %></p>
<% }) %>
<%- include footer %>

      到目前为止,博客系统已经完成了。还有个地方能够完善一下。如今没有作权限控制,无论登陆仍是未登陆均可以访问页面。稍稍修改一下,未登陆用户不能够进入文章页面和做者页面、不能够评论、不能够发布文章、不能够退出,当用户试图执行以上操做的时候,均跳转到登陆页面。

 

      我们在index.js中写一个函数检验用户是否登陆:

 

function checkLogin(req, res, next){
    if(!req.session.user){
        req.flash('error','请登陆'); 
        return res.redirect('/login');
    }
    next();
}

       而后在上面提到的几个路由控制前面加上checkLogin,如在app.get("/logout",function(){});以前加上:app.get('/logout',checkLogin); 

 

        对于登陆操做,应该只对未登陆用户开放,因此添加一个函数校验是否未登陆:

function checkNotLogin(req,res,next){
    if(req.session.user){
        req.flash('error','已登陆'); 
        return res.redirect('/');
    }
    next();
}

        而后在login对应的get和post处理前分别添加app.get('/login',checkNotLogin); 和app.post('/login',checkNotLogin);

 

        好了,到如今为止,粗糙的博客系统算是作好了,像csdn的标签功能其实和文章页面差很少,就不写了。

        有几个问题作一下小说明,也是我本身在第一次开发的过程当中遇到的:

        一、路由控制问题。要保证彼此的路由不会相互干扰,好比说,logout不会被做者页面的路由拦截,路由的书写顺序就很重要了。你能够试试把logou路由控制t放在user以后。因此在涉及到正则表达式类型的路由控制的时候,请认真思考路由的书写顺序,当你的路由解析出乎意料的时候,记得调整路由顺序。

        二、前面已经说过的样式问题。我第一次开发的时候,参考的是别人给出的解决方案,就是在article.ejs里面在引入一遍style.css,后来总以为那样不合理,才找出了解决方案。因此引入public下的文件的时候,建议用根目录。

        三、我写的这个从一开始到最后,数据结构都没有变过,省了不少。可是真正作开发的时候,不必定会那么顺利。好比我刚开始作的时候,每加一个功能就要修改一次数据结构,而后就会出现先前存进去的数据包含了后面才定义的属性,出现undefined。这时候也不用着急,先清空数据库,基本上就没问题了,还有问题的话,本身看控制台的错误提示,基本上也能够本身解决了。

        四、最后,题外话,写程序,思路要尽可能清晰一些,开始着手书写代码的时候,要细心,我的以为写代码能够遵循增量开发的原则,先搭好架子,后期再一步步扩展,一步步测试,这样便于调试。

相关文章
相关标签/搜索