packagehandlersimport("fmt""github.com/xueyuanjun/chitchat/models""net/http")// GET /threads/new
// 创建群组页面
funcNewThread(writerhttp.ResponseWriter,request*http.Request){_,err:=session(writer,request)iferr!=nil{http.Redirect(writer,request,"/login",302)}else{generateHTML(writer,nil,"layout","auth.navbar","new.thread")}}// POST /thread/create
// 执行群组创建逻辑
funcCreateThread(writerhttp.ResponseWriter,request*http.Request){sess,err:=session(writer,request)iferr!=nil{http.Redirect(writer,request,"/login",302)}else{err=request.ParseForm()iferr!=nil{fmt.Println("Cannot parse form")}user,err:=sess.User()iferr!=nil{fmt.Println("Cannot get user from session")}topic:=request.PostFormValue("topic")if_,err:=user.CreateThread(topic);err!=nil{fmt.Println("Cannot create thread")}http.Redirect(writer,request,"/",302)}}// GET /thread/read
// 通过 ID 渲染指定群组页面
funcReadThread(writerhttp.ResponseWriter,request*http.Request){vals:=request.URL.Query()uuid:=vals.Get("id")thread,err:=models.ThreadByUUID(uuid)iferr!=nil{fmt.Println("Cannot read thread")}else{_,err:=session(writer,request)iferr!=nil{generateHTML(writer,&thread,"layout","navbar","thread")}else{generateHTML(writer,&thread,"layout","auth.navbar","auth.thread")}}}
其中定义了三个方法,分别用于渲染群组创建表单页面、处理提交表单执行群组创建逻辑、以及根据指定 ID 渲染对应群组页面。前两个方法需要认证后才能访问,否则将用户重定向到登录页,群组详情页不需要认证即可访问,不过会根据是否认证返回不同的视图模板。
{{ define "content" }}
<formrole="form"action="/thread/create"method="post"><divclass="lead">Start a new thread with the following topic</div><divclass="form-group"><textareaclass="form-control"name="topic"id="topic"placeholder="Thread topic here"rows="4"></textarea><br/><br/><buttonclass="btn btn-lg btn-primary pull-right"type="submit">Start this thread</button></div></form>
{{ end }}
packagehandlersimport("fmt""github.com/xueyuanjun/chitchat/models""net/http")// POST /thread/post
// 在指定群组下创建新主题
funcPostThread(writerhttp.ResponseWriter,request*http.Request){sess,err:=session(writer,request)iferr!=nil{http.Redirect(writer,request,"/login",302)}else{err=request.ParseForm()iferr!=nil{fmt.Println("Cannot parse form")}user,err:=sess.User()iferr!=nil{fmt.Println("Cannot get user from session")}body:=request.PostFormValue("body")uuid:=request.PostFormValue("uuid")thread,err:=models.ThreadByUUID(uuid)iferr!=nil{fmt.Println("Cannot read thread")}if_,err:=user.CreatePost(thread,body);err!=nil{fmt.Println("Cannot create post")}url:=fmt.Sprint("/thread/read?id=",uuid)http.Redirect(writer,request,url,302)}}
我们只定义了一个创建主题的处理器方法,在该处理器方法中,仍然会验证用户是否已认证,只有认证用户才能创建主题,我们最后会调用 user.CreatePost 方法根据群组 ID、用户 ID 和主题内容创建新的主题记录,保存成功后,会返回创建该主题的群组详情页,并将与该群组关联的所有主题渲染出来。关于数据库和视图模板引擎的语法细节,后面我们会在对应的独立教程中详细介绍。