# 13.5 实现博客的增删改

前面介绍了beego框架实现的整体构思以及部分实现的伪代码，这小节介绍通过beego建立一个博客系统，包括博客浏览、添加、修改、删除等操作。
## 博客目录
博客目录如下所示：

	/main.go
	/views:
	    /view.tpl
	    /new.tpl
	    /layout.tpl
	    /index.tpl
	    /edit.tpl
	/models/model.go
	/controllers:
	    /index.go
		/view.go
		/new.go
		/delete.go
		/edit.go			


## 博客路由
博客主要的路由规则如下所示：

	//显示博客首页
	beego.Router("/", &controllers.IndexController{})
	//查看博客详细信息
	beego.Router("/view/:id([0-9]+)", &controllers.ViewController{})
	//新建博客博文
	beego.Router("/new", &controllers.NewController{})
	//删除博文
	beego.Router("/delete/:id([0-9]+)", &controllers.DeleteController{})
	//编辑博文
	beego.Router("/edit/:id([0-9]+)", &controllers.EditController{})


## 数据库结构
数据库设计最简单的博客信息

	CREATE TABLE entries (
	    id INT AUTO_INCREMENT,
	    title TEXT,
	    content TEXT,
	    created DATETIME,
	    primary key (id)
	);

## 控制器
IndexController:

	type IndexController struct {
		beego.Controller
	}
	
	func (this *IndexController) Get() {
		this.Data["blogs"] = models.GetAll()
		this.Layout = "layout.tpl"
		this.TplNames = "index.tpl"
	}
	
ViewController:

	type ViewController struct {
		beego.Controller
	}
	
	func (this *ViewController) Get() {
		id, _ := strconv.Atoi(this.Ctx.Input.Params(":id"))
		this.Data["Post"] = models.GetBlog(id)
		this.Layout = "layout.tpl"
		this.TplNames = "view.tpl"
	}

NewController

	type NewController struct {
		beego.Controller
	}
	
	func (this *NewController) Get() {
		this.Layout = "layout.tpl"
		this.TplNames = "new.tpl"
	}
	
	func (this *NewController) Post() {
		inputs := this.Input()
		var blog models.Blog
		blog.Title = inputs.Get("title")
		blog.Content = inputs.Get("content")
		blog.Created = time.Now()
		models.SaveBlog(blog)
		this.Ctx.Redirect(302, "/")
	}		

EditController

	type EditController struct {
		beego.Controller
	}
	
	func (this *EditController) Get() {
		id, _ := strconv.Atoi(this.Ctx.Input.Params(":id"))
		this.Data["Post"] = models.GetBlog(id)
		this.Layout = "layout.tpl"
		this.TplNames = "new.tpl"
	}
	
	func (this *EditController) Post() {
		inputs := this.Input()
		var blog models.Blog
		blog.Id, _ = strconv.Atoi(inputs.Get("id"))
		blog.Title = inputs.Get("title")
		blog.Content = inputs.Get("content")
		blog.Created = time.Now()
		models.SaveBlog(blog)
		this.Ctx.Redirect(302, "/")
	}
	
DeleteController

	type DeleteController struct {
		beego.Controller
	}
	
	func (this *DeleteController) Get() {
		id, _ := strconv.Atoi(this.Ctx.Input.Params(":id"))
		blog := GetBlog(id int)
		this.Data["Post"] = blog
		models.DelBlog(blog)
		this.Ctx.Redirect(302, "/")
	}	

## model层

	package models
	
	import (
		"database/sql"
		"github.com/astaxie/beedb"
		_ "github.com/ziutek/mymysql/godrv"
		"time"
	)
	
	type Blog struct {
		Id      int `PK`
		Title   string
		Content string
		Created time.Time
	}
	
	func GetLink() beedb.Model {
		db, err := sql.Open("mymysql", "blog/astaxie/123456")
		if err != nil {
			panic(err)
		}
		orm := beedb.New(db)
		return orm
	}
	
	func GetAll() (blogs []Blog) {
		db := GetLink()
		db.FindAll(&blogs)
		return
	}
	
	func GetBlog(id int) (blog Blog) {
		db := GetLink()
		db.Where("id=?", id).Find(&blog)
		return
	}
	
	func SaveBlog(blog Blog) (bg Blog) {
		db := GetLink()
		db.Save(&blog)
		return bg
	}
	
	func DelBlog(blog Blog) {
		db := GetLink()
		db.Delete(&blog)
		return
	}


## view层

layout.tpl

	<html>
	<head>
	    <title>My Blog</title>
	    <style>
	        #menu {
	            width: 200px;
	            float: right;
	        }
	    </style>
	</head>
	<body>
	
	<ul id="menu">
	    <li><a href="/">Home</a></li>
	    <li><a href="/new">New Post</a></li>
	</ul>
	
	{{.LayoutContent}}
	
	</body>
	</html>
	
index.tpl

	<h1>Blog posts</h1>

	<ul>
	{{range .blogs}}
	    <li>
	        <a href="/view/{{.Id}}">{{.Title}}</a> 
	        from {{.Created}}
	        <a href="/edit/{{.Id}}">Edit</a>
	        <a href="/delete/{{.Id}}">Delete</a>
	    </li>
	{{end}}
	</ul>

view.tpl

	<h1>{{.Post.Title}}</h1>
	{{.Post.Created}}<br/>
	
	{{.Post.Content}}				

new.tpl

	<h1>New Blog Post</h1>
	<form action="" method="post">
	标题:<input type="text" name="title"><br>
	内容：<textarea name="content" colspan="3" rowspan="10"></textarea>
	<input type="submit">
	</form>

edit.tpl
	
	<h1>Edit {{.Post.Title}}</h1>

	<h1>New Blog Post</h1>
	<form action="" method="post">
	标题:<input type="text" name="title" value="{{.Post.Title}}"><br>
	内容：<textarea name="content" colspan="3" rowspan="10">{{.Post.Content}}</textarea>
	<input type="hidden" name="id" value="{{.Post.Id}}">
	<input type="submit">
	</form>

## links
   * [目录](<preface.md>)
   * 上一章: [日志和配置设计](<13.4.md>)
   * 下一节: [小结](<13.6.md>)
