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。這時候也不用着急,先清空數據庫,基本上就沒問題了,還有問題的話,本身看控制檯的錯誤提示,基本上也能夠本身解決了。

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

相關文章
相關標籤/搜索