go 博客系统

一、Beego Web框架

使用go get下载安装bee工具与Beego
  • Bee:https://github.com/astaxie/bee
  • Beego:https://github.com/astaxie/beego

    1
    2
    3
    4
    5
    6
    7
    8
    安装
    go get github.com/astaxie/beego
    更新
    go get -u github.com/astaxie/beego
    安装
    go get github.com/beego/bee
    更新
    go get -u github.com/beego/bee
  • 新建项目

    bee new goblog
    

  • 运行程序

    bee run beeblog
    

    二、模板用法讲解

    模板基础应用
  • if

    1
    2
    3
    this.Data["TrueCond"] = true
    this.Data["FalseCond"] = false
    {{if .FalseCond}} {{else}} false condition {{end}}
  • with

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type u struct {
Name string
Age int
Sex string
}
User := &u{
Name: "Joe",
Age: 20,
Sex: "Male",
}
this.Data["User"] = User
{{.User.Name}};{{.User.Age}};{{.User.Sex}}
{{with .User}}
{{.Name}};{{.Age}};{{.Sex}}
{{end}}
  • range
    1
    2
    3
    4
    5
    num := []int{1,2,3,4,5,6,7,8,9,0}
    this.Data["Nums"]=nums;
    {{range .Nums}}
    {{.}}
    {{end}}
模板高级应用
  • 模板变量

    1
    2
    3
    this.Data["TpVar"] = "hey gus"
    {{StpVal := .TpVar}}
    {{StpVar}}
  • 模板函数(beeGo自制)

    1
    2
    3
    4
    5
    this.Data["Html"] = "<dic>hello beego</div>"
    {{str2html .Html}}
    ------
    this.Data["Pipe"] = "<dic>hello beego</div>"
    {{.Pipe | htmlquoto}}
  • 模板嵌套

    • 定义一个模板

      1
      2
      3
      4
      {{define "test"}}
      <div>
      this is test template
      </div>
    • 使用模板

      1
      2
      3
      <div>
      {{template "test"}}
      </div>
  • 参考文献

三、数据库ORM操作

创建model
  • 在models文件下新建一个models.go文件
  • 安装所需包

    1
    2
    3
    go get github.com/Unknwon/com
    go get github.com/mattn/go-sqlite3
  • 写入数据 model包含分类和文章两个表

    • beeBlog/models.go
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      package models
      import (
      "os"
      "path"
      "time"
      "github.com/Unknwon/com"
      "github.com/astaxie/beego/orm"
      _ "github.com/mattn/go-sqlite3"
      )
      const (
      _DB_NAME = "data/beeblog.db"
      _SQLITE3_DRIVER = "sqlite3"
      )
      //_只执行其初始换函数,不进行函数调用
      type Category struct {
      Id int64
      Title string
      Create time.Time `orm:"index"` //创建日期 tags建立索引
      View int64 `orm:"index"` //浏览量
      TopicTime time.Time `orm:"index"` //最后一篇文章发表时间
      TopicCount int64
      TopicLastUserId int64
      }
      type Topic struct {
      Id int64
      Uid int64
      Title string
      Content string `orm:"size(5000)"`
      Attachment string //附件
      Created time.Time `orm:"index"`
      Updated time.Time `orm:"index"`
      View int64 `orm:"index"` //浏览量
      Author string
      ReplyTime time.Time `orm:"index"` //回复时间
      ReplyCount int64
      RepleyLastUserId int64 //回复者的ID
      }
      func () {
      if !com.IsExist(_DB_NAME) {
      os.MkdirAll(path.Dir(_DB_NAME), os.ModePerm)//data文件夹 默认权限
      os.Create(_DB_NAME)
      }
      orm.RegisterModel(new(Category),new(Topic))
      //orm.RegisterDriver(_SQLITE3_DRIVER,orm.DR_Sqlite)
      orm.RegisterDataBase("default",_SQLITE3_DRIVER,_DB_NAME,10)
      }
main 下加载model 模型 然后自动建表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
import (
"beeblog/controllers"
"beeblog/models"
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
)
//_ "beeblog/routers"
func init(){
models.RegisterDB()
}
func main() {
orm.Debug = true
orm.RunSyncdb("default",false,true)//false=每次运行不重新建表 true=是否打印相关信息
beego.Router("/",&controllers.MainController{})
beego.Run()
}

四、登录操作

html代码
  • head模板

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    {{define "header"}}
    <html>
    <head>
    <link rel="shortcut icon" href="/static/img/favicon.png">
    <meta http-equiv="Content-type" content="text/html;charset=utf-8">
    <!--stylesheet-->
    <link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css">
    {{end}}
  • 导航栏模板

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    {{define "navbar"}}
    <a class="navbar-brand" href="/">我的博客</a>
    <div>
    <ul class="nav navbar-nav">
    <li {{if .IsHome}}class="active" {{end}}> <a href="/">首页</a></li>
    <li {{if .IsCategory}}class="active" {{end}}> <a href="/category">分类</a></li>
    <li {{if .IsTopic}}class="active" {{end}}><a href="/topic">文章</a></li>
    </ul>
    </div>
    <div class="pull-right">
    <ul class="nav navbar-nav">
    {{if .IsLogin}}
    <li><a href="/login?exit=true">退出</a></li>
    {{else}}
    <li><a href="/login">管理员登录</a></li>
    {{end}}
    </ul>
    </div>
    {{end}}
  • 主页

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    {{template "header"}}
    <title>首页-我的beego博客</title>
    </head>
    <body>
    <header class="navbar navbar-static-top bs-docs-nav" id="top">
    <!--{{template "navbar" .}} .为了对模板进行逻辑操作 -->
    <div class="navbar navbar-default navbar-fixed-top">
    <div class="container">
    {{template "navbar" .}}
    </div>
    </div>
    </header>
    <!-- <div class="jumbotron masthead"> </div>-->
    <!-- Page content of course! -->
    <main class="bs-docs-masthead" id="content" tabindex="-1">
    <div class="container">
    <div class="page-header">
    <h1>我的第一篇文章</h1>
    <h6 class="text-muted">文章发表与2017年x月x日,共有100次浏览,200个评论</h6>
    <p>大家好,这是我的第一篇文章,多谢浏览</p>
    </div>
    </div>
    </main>
    <footer class="bs-docs-footer">
    </footer>
    <script type="text/javascript" src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
    <script type="text/javascript" src="/static/js/bootstrap.min.js"></script>
    </body>
    </html>
  • 登录页面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    {{template "header"}}
    <title>登录-我的beego博客</title>
    </head>
    <body>
    <div class="container" style="width: 600px">
    <form method="POST" action="/login">
    <div class="form-group">
    <label>Account</label>
    <input id="uname" type="text" class="form-control" placeholder="Enter Account" name="uname">
    </div>
    <div class="form-group">
    <label>Password</label>
    <input id="pwd" type="password" class="form-control" placeholder="Password" name="pwd">
    </div>
    <div class="checkbox">
    <label>
    <input type="checkbox" name="autoLogin"> 自动登录
    </label>
    </div>
    <button type="submit" class="btn btn-default" onclick="return checkInput()">登录</button>
    <button class="btn btn-default" onclick="return backToHome()">返回</button>
    </form>
    <script type="text/javascript">
    function checkInput(){
    var uname=document.getElementById("uname");
    if(uname.value.length==0){
    alert("请输入账号");
    return false;
    }
    var pwd=document.getElementById("pwd");
    if(pwd.value.length==0){
    alert("请输入密码");
    return false;
    }
    return true;
    }
    </script>
    <script type="text/javascript">
    function backToHome(){
    window.location.href="/"
    return false;
    }
    </script>
    </div>
    </body>
    </html>
后端代码
  • 配置文件存储账号密码(一个) app.conf

    1
    2
    3
    4
    5
    appname = beeblog
    httpport = 8080
    runmode = dev
    uname=admin
    pwd=admin
  • login.go

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    package controllers
    import (
    "github.com/astaxie/beego"
    "github.com/astaxie/beego/context"
    )
    type LoginController struct {
    beego.Controller
    }
    func (this *LoginController) Get() {
    //退出
    isExit := this.Input().Get("exit") == "true"
    if isExit {
    this.Ctx.SetCookie("uname", "", -1, "/")
    this.Ctx.SetCookie("pwd", "", -1, "/")
    this.Redirect("/", 301)
    return
    }
    this.TplName = "login.html"
    }
    func (this *LoginController) Post() {
    uname := this.Input().Get("uname")
    pwd := this.Input().Get("pwd")
    autoLogin := this.Input().Get("autoLogin")=="on"
    if beego.AppConfig.String("uname") == uname && beego.AppConfig.String("pwd") == pwd{
    maxAge := 0
    if autoLogin{
    maxAge = 1<<31-1 //1左移31位减去1
    }
    this.Ctx.SetCookie("uname",uname,maxAge,"/")
    this.Ctx.SetCookie("pwd",pwd,maxAge,"/")
    }
    this.Redirect("/",301)//重定向
    return
    }
    func checkAccount(ctx *context.Context) bool{
    ck,err := ctx.Request.Cookie("uname")
    if err != nil {
    return false
    }
    uname := ck.Value
    ck,err = ctx.Request.Cookie("pwd")
    if err != nil {
    return false
    }
    pwd := ck.Value
    return beego.AppConfig.String("uname") == uname && beego.AppConfig.String("pwd") == pwd
    }
  • home.go

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package controllers
    import (
    "github.com/astaxie/beego"
    )
    type MainController struct {
    beego.Controller
    }
    func (this *MainController) Get() {
    this.Data["IsHome"] = true;
    this.TplName = "home.html"
    this.Data["IsLogin"] = checkAccount(this.Ctx)
    }

五、分类

html代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
{{template "header"}}
<title>分类-我的 Beego 博客</title>
</head>
<body>
<div class="navbar navbar-default navbar-fixed-top">
<div class="container">
{{template "navbar".}}
</div>
</div>
<div class="container">
<h1>分类列表</h1>
<form method="GET" action="/category">
<div class="form-group">
<label>分类名称</label>
<input id="name" type="text" class="form-control" placeholder="Enter category" name="name">
</div>
<input type="hidden" name="op" value="add">
<button type="submit" class="btn btn-default" onclick="return checkInput()">添加</button>
</form>
<script type="text/javascript">
function checkInput() {
var name = document.getElementById("name");
if (name.value.length == 0) {
alert("请输入分类名称");
return false;
}
return true;
}
</script>
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>名称</th>
<th>文章数</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{{range .Categories}}
<th>{{.Id}}</th>
<th>{{.Title}}</th>
<th>{{.TopicCount}}</th>
<th><a href="/category?op=del&id={{.Id}}">删除</a></th>
{{end}}
</tbody>
</table>
</div>
<script type="text/javascript" src="http://cdn.staticfile.org/jquery/2.1.1-rc2/jquery.min.js"></script>
<script type="text/javascript" src="/static/js/bootstrap.min.js"></script>
</body>
</html>
后端代码
  • category.go

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    package controllers
    import (
    "beeblog/models"
    "github.com/astaxie/beego"
    )
    type CategoryController struct {
    beego.Controller
    }
    func (this *CategoryController) Get() {
    op := this.Input().Get("op")
    switch op {
    case "add":
    name := this.Input().Get("name")
    if len(name) == 0 {
    break
    }
    err := models.AddCategory(name)
    if err != nil {
    beego.Error(err)
    }
    this.Redirect("/category", 301)
    return
    case "del":
    id := this.Input().Get("id")
    if len(id) == 0 {
    break
    }
    err := models.DelCategory(id)
    if err != nil {
    beego.Error(err)
    }
    this.Redirect("/category", 301)
    return
    }
    this.Data["IsLogin"] = checkAccount(this.Ctx)
    this.Data["IsCategory"] = true
    this.TplName = "category.html"
    var err error
    this.Data["Categories"], err = models.GetAllCategories()
    if err != nil {
    beego.Error(err)
    }
    }
  • models.go(部分)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    //添加分类
    func AddCategory(name string) error {
    o := orm.NewOrm()
    cate := &Category{Title: name,Created:time.Now(),TopicTime:time.Now()}
    qs := o.QueryTable("Category")
    err := qs.Filter("Title", name).One(cate)
    if err == nil {
    return err
    }
    _, err = o.Insert(cate)
    if err != nil {
    return err
    }
    return nil
    }
    //获取所以分类
    func GetAllCategories() ([]*Category, error) {
    o := orm.NewOrm()
    cates := make([]*Category, 0)
    qs := o.QueryTable("Category")
    _, err := qs.All(&cates)
    return cates, err
    }
    //删除分类
    func DelCategory(id string) error {
    //字符串转换成十进制的int64
    cid, err := strconv.ParseInt(id, 10, 64)
    if err != nil {
    return err
    }
    o := orm.NewOrm()
    cate := &Category{Id: cid}
    _, err = o.Delete(cate)
    return err
    }
  • main.go(部分)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import (
    "beeblog/controllers"
    )
    func main() {
    orm.Debug = true //打印所有orm信息,方便调试
    //第一个是否每次需要重建表,,是否打印相关信息
    orm.RunSyncdb("default",false,true)//false=每次运行不重新建表 true=是否打印相关信息
    beego.Router("/",&controllers.MainController{})
    beego.Router("/category", &controllers.CategoryController{})
    beego.Router("/login",&controllers.LoginController{})
    beego.Run()
    }