nodejs--express開發博客系統(三)

    上一節已經實現了登錄、註冊、發表文章和文章讀取的功能,今天咱加上評論、文章頁面和作者頁面。

     評論只能在進入文章頁面後才能進行,所以咱們先寫文章頁面。

     在上一節的代碼中,我已經給文章標題添加了超鏈接了,

<a href="/<%= post.user %>/<%= post.time.day%>/<%= post.title %>"><%= post.title %></a>
     根據這個鏈接地址,進入文章頁面的路由控制就可以寫成這樣:

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.ejs
<%- 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的路徑寫成這樣:

<link rel="stylesheet" href="/stylesheets/style.css">
      好了,ok了!

     現在在文章頁面後面加上評論,完整的article.ejs爲:

<%- 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的標籤功能其實和文章頁面差不多,就不寫了。

        有幾個問題做一下小說明,也是我自己在第一次開發的過程中遇到的:

        1、路由控制問題。要保證彼此的路由不會相互干擾,比如說,logout不會被作者頁面的路由攔截,路由的書寫順序就很重要了。你可以試試把logou路由控制t放在user之後。所以在涉及到正則表達式類型的路由控制的時候,請認真思考路由的書寫順序,當你的路由解析出乎意料的時候,記得調整路由順序。

        2、前面已經說過的樣式問題。我第一次開發的時候,參考的是別人給出的解決方案,就是在article.ejs裏面在引入一遍style.css,後來總覺得那樣不合理,才找出瞭解決方案。所以引入public下的文件的時候,建議用根目錄。

        3、我寫的這個從一開始到最後,數據結構都沒有變過,省了很多。但是真正做開發的時候,不一定會那麼順利。比如我剛開始做的時候,每加一個功能就要修改一次數據結構,然後就會出現先前存進去的數據包含了後面才定義的屬性,出現undefined。這時候也不用着急,先清空數據庫,基本上就沒問題了,還有問題的話,自己看控制檯的錯誤提示,基本上也可以自己解決了。

        4、最後,題外話,寫程序,思路要儘量清晰一些,開始着手書寫代碼的時候,要細心,個人覺得寫代碼可以遵循增量開發的原則,先搭好架子,後期再一步步擴展,一步步測試,這樣便於調試。

       




      




      


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章