【Go web開發之revel+mgo】第4章 實現評論功能

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

sorry,各位在開始這一章之前請各位先到,第5章把整個項目的css  copy出來,這一章忘了加,本來想在後面加的,但是發現頁面的內容太多了


1.設計評論頁面

上一章我們做了簡單的寫blog和顯示功能,這裡不得不說一下,首先,我們的blog裡面不能加圖片連結這樣的東西,不支援markdown文法。博主比較懶,嘗試找了幾個外掛程式發現不滿意之後就不想嘗試了(其實能找到github編寫wiki的編輯器才是我想要的,有誰知道的告訴我哦),大家可以自己嘗試去找一些自己喜歡的編輯器(雖然revel中文社區的那個已經很不錯了,但是彈出框風格很不喜歡,golang社區的編輯器也很強,但也不是我喜歡的風格,你妹啊,這麼挑剔。。。。),總之,大家可以參考一下,喜歡就用。
在views/App下面建立BlogInfor.html 內容:
{{set . "title" "Bloginfor - GBlog" }}{{set . "home" "active" }}{{template "header.html" .}}<div class="content">    <div class="infor-content">        <div class="infor-header">          <h3>Title</h3>          <div class="subject-infor">            <span class="label label-success">Author</span>   <span>jov123@163.com</span>              <span class="label label-default">Date</span>  2014-04-25 15:04              <span class="label label-info">Read</span>  1          </div>        </div>        <div class="infor-body">          this is the subject        </div>    </div>    <div class="comments">        <span>回複</span>        <hr>        <dl class="the-comments">          <dd >            <span class="label label-default pull-right">#1</span>            <div class="user-info">              <a href="#"><strong>omind@163.com</strong></a> •              2014-04-25 16:04            </div>            <div class="user-comment">              <p>nice!</p>            </div>          </dd>        </dl>    </div>    <div class="comments">        <div class="comment-form">          <form action="/docomment" method="post">            <input type="hidden" name="id" value="{{.blog.Id.Hex}}">            <input type="hidden" name="rcnt" value="{{.rcnt}}">            <div class="form-group">              <label >Email</label>              {{with $field := field "comment.Email" .}}              <input type="email" class="form-control" id="{{$field.Id}}" name="{{$field.Name}}"  placeholder="Your email" required value="{{if $field.Flash}}{{$field.Flash}}{{else}}{{$field.Value}}{{end}}">              <span class="help-inline erro">{{$field.Error}}</span>              {{end}}            </div>            <div class="form-group">              <label >Comment</label>              {{with $field := field "comment.Content" .}}              <textarea class="form-control" id="{{$field.Id}}" name="{{$field.Name}}" rows="6" placeholder="Enter the comment" required >{{if $field.Flash}}{{$field.Flash}}{{else}}{{$field.Value}}{{end}}</textarea>              {{end}}            </div>            <div class="form-group">              <button type="submit" class="btn btn-success">Submit</button>            </div>          </form>        </div>    </div></div>{{template "footer.html" .}}

在app/controllers/app.go裡面添加我們的處理方法:
func (c App) BlogInfor() revel.Result {return c.Render()}

在conf/routes裡面添加路徑:
GET     /bloginfor               App.BlogInfor

ok在地址裡面用http://localhost:9000/bloginfor訪問看看,效果:

下面我們來實現它。

2.實現評論功能

首先看一下我們的Index.html裡面的title的連結內容:
/bloginfor/{{$blog.Id.Hex}}/{{$blog.ReadCnt}}

恩,對,我們傳遞了blog的id和閱讀次數,為什麼要傳閱讀次數呢,因為從這個連結點進去的時候我們要把閱讀次數加1,但是如果我們不傳遞,那麼到詳細頁面的時候應該是直接將db裡面的資料增加,這樣就有問題了,我在詳細頁面一直按F5重新整理,發現閱讀次數飛快的增加,這讓我很無奈,怎麼版辦呢,把閱讀次數也傳過來把,至少把原來的一步增加了2步,稍微的緩解一下把,但是仍然不知最好的方法啊,最好的方法是,我們擷取,請求使用者的 IP,做判斷,只能為這個Ip增加一次,這都是後話了。
好了我們修改一下路徑的配置conf/routes:
GET     /bloginfor/:id/:rcnt                    App.BlogInfor

把app/controllers/app.go裡面的BlogInfor方法也加兩個參數:
func (c App) BlogInfor(id string,rcnt int) revel.Result {return c.Render()}

好,我們這次從首頁點擊我們blog的title進去看看,是不是能正常進入詳細頁面。
我這邊是ok的,我們往下進行,首先app/controllers/app.go的BlogInfor方法,修改如下:
func (c App) BlogInfor(id string,rcnt int) revel.Result {dao, err := models.NewDao()if err != nil {c.Response.Status = 500return c.RenderError(err)}defer dao.Close()blog := dao.FindBlogById(id)if(blog.ReadCnt==rcnt){blog.ReadCnt = rcnt+1dao.UpdateBlogById(id,blog)}return c.Render(blog,rcnt)}

我們去找到這個blog,並且把閱讀次數做一下更新,看一下裡面的判斷,我們是把閱讀次數和db中的相比較,只有相等的情況才去更新,這樣確實增加了2步。不過,如果你有時間,你也可以採用另外一種方法,就是把閱讀次數加密(可逆的加密),解密之後再與db中的比較,這樣的話,使用者想要修改加密後的東西並不是一件容易的事件。
那麼我們的model也要有對應的方法,開啟 app/models/blog.go,添加方法:
func (dao *Dao) FindBlogById(id string) *Blog{blogCollection := dao.session.DB(DbName).C(BlogCollection)blog := new(Blog)query := blogCollection.Find(bson.M{"id": bson.ObjectIdHex(id)})query.One(blog)return blog}func (dao *Dao) UpdateBlogById(id string,blog *Blog) {blogCollection := dao.session.DB(DbName).C(BlogCollection)err := blogCollection.Update(bson.M{"id": bson.ObjectIdHex(id)}, blog)if err!=nil{revel.WARN.Printf("Unable to update blog: %v error %v", blog, err)}}

一個是尋找,一個是更新,沒什麼好說的。
開啟views/App/BlogInfor.html修改成:
{{set . "title" "Bloginfor - GBlog" }}{{set . "home" "active" }}{{template "header.html" .}}<div class="content">    {{if .blog}}    <div class="infor-content">        <div class="infor-header">          <h3>{{.blog.Title}}</h3>          <div class="subject-infor">            <span class="label label-success">Author</span>   <span>{{.blog.Email}}</span>              <span class="label label-default">Date</span>  {{.blog.CDate.Format "2006-01-02 15:04"}}              <span class="label label-info">Read</span>  {{.blog.ReadCnt}}          </div>        </div>        <div class="infor-body">          {{.blog.Subject}}        </div>    </div>    <div class="comments">        <span>回複</span>        <hr>        <dl class="the-comments">          <dd >            <span class="label label-default pull-right">#1</span>            <div class="user-info">              <a href="#"><strong>omind@163.com</strong></a> •              2014-04-25 16:04            </div>            <div class="user-comment">              <p>nice!</p>            </div>          </dd>        </dl>    </div>    <div class="comments">        <div class="comment-form">          <form action="/docomment" method="post">            <input type="hidden" name="id" value="{{.blog.Id.Hex}}">            <input type="hidden" name="rcnt" value="{{.rcnt}}">            <div class="form-group">              <label >Email</label>              {{with $field := field "comment.Email" .}}              <input type="email" class="form-control" id="{{$field.Id}}" name="{{$field.Name}}"  placeholder="Your email" required value="{{if $field.Flash}}{{$field.Flash}}{{else}}{{$field.Value}}{{end}}">              <span class="help-inline erro">{{$field.Error}}</span>              {{end}}            </div>            <div class="form-group">              <label >Comment</label>              {{with $field := field "comment.Content" .}}              <textarea class="form-control" id="{{$field.Id}}" name="{{$field.Name}}" rows="6" placeholder="Enter the comment" required >{{if $field.Flash}}{{$field.Flash}}{{else}}{{$field.Value}}{{end}}</textarea>              {{end}}            </div>            <div class="form-group">              <button type="submit" class="btn btn-success">Submit</button>            </div>          </form>        </div>    </div>    {{end}}</div>{{template "footer.html" .}}

顯示了 blog資訊。好,點進去看看效果:



ok,我們來做評論。在app/models下建立comment.go 內容:
package modelsimport ("github.com/revel/revel""labix.org/v2/mgo/bson""time")type Comment struct{BlogId bson.ObjectId Email stringCDate time.TimeContent string}func (comment *Comment) Validate(v *revel.Validation) {v.Check(comment.Email,revel.Required{},revel.MaxSize{50},)v.Email(comment.Email)v.Check(comment.Content,revel.Required{},revel.MinSize{1},revel.MaxSize{1000},)}func (dao *Dao) InsertComment(comment *Comment) error {commCollection := dao.session.DB(DbName).C(CommentCollection)//set the timecomment.CDate = time.Now();err := commCollection.Insert(comment)if err != nil {revel.WARN.Printf("Unable to save Comment: %v error %v", comment, err)}return err}func (dao *Dao) FindCommentsByBlogId(id bson.ObjectId) []Comment{commCollection := dao.session.DB(DbName).C(CommentCollection)comms := []Comment{}query := commCollection.Find(bson.M{"blogid":id}).Sort("CDate")query.All(&comms)return comms}

跟我們的blog.go很相似,不用多解釋。有了dao,我們來做邏輯,還是先做提交評論的功能,看下 我們的BlogInfo.html頁面。最後的form表單,裡面的東西跟我們上一章講的差不多。
在app/controllers下面建立wcomment.go,為什麼以w開頭,write嘛,內容:
package controllersimport ("github.com/revel/revel""GBlog/app/models""strings")type WComment struct {App}func (c WComment) Docomment(id string,rcnt int,comment *models.Comment) revel.Result {if len(id)==0{return c.Redirect(App.Index)}dao, err := models.NewDao()if err != nil {c.Response.Status = 500return c.Redirect(App.Index)}defer dao.Close()blog := dao.FindBlogById(id)if blog==nil {return c.Redirect(App.Index)}comment.BlogId = blog.Idcomment.Content = strings.TrimSpace(comment.Content)comment.Email = strings.TrimSpace(comment.Email)comment.Validate(c.Validation)if c.Validation.HasErrors() {c.Validation.Keep()c.FlashParams()c.Flash.Error("Errs:The email and the content should not be null,or the maxsize of email is 50.")return c.Redirect("/bloginfor/%s/%d",id,rcnt)}err = dao.InsertComment(comment)if err!=nil {c.Response.Status = 500return c.RenderError(err)}blog.CommentCnt++dao.UpdateBlogById(id,blog)return c.Redirect("/bloginfor/%s/%d",id,rcnt)}

看一下裡面的邏輯,我們先去尋找一下,有沒有這個blog對象,沒有的話,就直接 返回到Index頁面,然後是comment的校正,最後我們的blog的評論次數加1。最後的c.Redirect("/bloginfor/%s/%d",id,rcnt)是讓它再次回到infor頁面的。
好,添加我們的路徑,conf/routes:
POST    /docomment                 WComment.Docomment

你可以試試能不能提交成功了。雖然還看不到什麼結果。下面來顯示我們的評論,在app/controllers/app.go的BlogInfor方法裡,return之前加上下面的代碼:
comments := dao.FindCommentsByBlogId(blog.Id);if len(comments)==0&&blog.CommentCnt!=0{blog.CommentCnt=0;dao.UpdateBlogById(id,blog)}else if len(comments)!=blog.CommentCnt{blog.CommentCnt=len(comments);dao.UpdateBlogById(id,blog)}

最後的return修改為:
return c.Render(blog,rcnt,comments)

開啟views/App/BlogInfor.html,將其中的塊:
<div class="comments">        <span>回複</span>        <hr>        <dl class="the-comments">          <dd >            <span class="label label-default pull-right">#1</span>            <div class="user-info">              <a href="#"><strong>omind@163.com</strong></a> •              2014-04-25 16:04            </div>            <div class="user-comment">              <p>nice!</p>            </div>          </dd>        </dl>    </div>


修改為:
{{if .comments}}    <div class="comments">        <span>回複</span>        <hr>        <dl class="the-comments">           {{range $index,$comment := .comments}}          <dd >            <span class="label label-default pull-right">#{{pls $index 1}}</span>            <div class="user-info">              <a href="#"><strong>{{$comment.Email}}</strong></a> •              {{$comment.CDate.Format "2006-01-02 15:04" }}            </div>            <div class="user-comment">              <p>{{$comment.Content}}</p>            </div>          </dd>          {{end}}        </dl>    </div>    {{end}}

哎呦,不錯哦,基本上做完了,為什麼說基本上呢,因為你現在重新整理頁面的話應該會有錯,看到了嗎?上面的代碼:
{{pls $index 1}}
這個是用來顯示樓層的的東西,這個什麼呢,是我們自訂的模板,這裡不得不感謝revel中文社區的kevin,如果我們直接用$index它是從0開始的,這。。。
好,開啟我們的app/init.go,話說裡面還有很多我也不知到的東西,就不給大家講了,func init() 裡面添加:
revel.TemplateFuncs["pls"] = func(a, b int) int { return a + b }

就是定義了一個簡單的模板方法。
好了嗎。各位,趕快試試期待已久的評論功能把。


nice。你成功了嗎?
源碼地址:https://github.com/joveth/GBlog

交流QQ:158325682


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.