Go博客實戰教程,是一個練手級項目教程,使用原生Go開發,未使用任何框架。
如何使用原生Go開發一個web項目
循序漸進,掌握編程思維和思路
初步具有工程思維,能適應一般的開發工作
1. 搭建項目
package mainimport ("encoding/json""log""net/http"
)type IndexData struct {Title string `json:"title"`Desc string `json:"desc"`
}
func index(w http.ResponseWriter,r *http.Request) {w.Header().Set("Content-Type","application/json")var indexData IndexDataindexData.Title = "碼神之路go博客"indexData.Desc = "現在是入門教程"jsonStr,_ := json.Marshal(indexData)w.Write(jsonStr)
}func main() {//程序入口,一個項目 只能有一個入口//web程序,http協議 ip portserver := http.Server{Addr: "127.0.0.1:8080",}http.HandleFunc("/",index)if err := server.ListenAndServe();err != nil{log.Println(err)}
}
2. 響應頁面
func indexHtml(w http.ResponseWriter,r *http.Request) {t := template.New("index.html")viewPath, _ := os.Getwd()t,_ = t.ParseFiles(viewPath + "/template/index.html")var indexData IndexDataindexData.Title = "碼神之路go博客"indexData.Desc = "現在是入門教程"err := t.Execute(w,indexData)fmt.Println(err)
}func main() {//程序入口,一個項目 只能有一個入口//web程序,http協議 ip portserver := http.Server{Addr: "127.0.0.1:8080",}http.HandleFunc("/",index)http.HandleFunc("/index.html",indexHtml)if err := server.ListenAndServe();err != nil{log.Println(err)}
}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>hello mszlu blog!!
{{.Title}}{{.Desc}}
</body>
</html>
3. 首頁
3.1 頁面解析
func index(w http.ResponseWriter,r *http.Request) {var indexData IndexDataindexData.Title = "碼神之路go博客"indexData.Desc = "現在是入門教程"t := template.New("index.html")//1. 拿到當前的路徑path,_ := os.Getwd()//訪問博客首頁模板的時候,因為有多個模板的嵌套,解析文件的時候,需要將其涉及到的所有模板都進行解析home := path + "/template/home.html"header := path + "/template/layout/header.html"footer := path + "/template/layout/footer.html"personal := path + "/template/layout/personal.html"post := path + "/template/layout/post-list.html"pagination := path + "/template/layout/pagination.html"t,_ = t.ParseFiles(path + "/template/index.html",home,header,footer,personal,post,pagination)//頁面上涉及到的所有的數據,必須有定義t.Execute(w,indexData)
}
3.2 首頁數據格式定義
config/config.go
package configtype Viewer struct {Title stringDescription stringLogo stringNavigation []stringBilibili stringAvatar stringUserName stringUserDesc string
}
type SystemConfig struct {AppName stringVersion float32CurrentDir stringCdnURL stringQiniuAccessKey stringQiniuSecretKey stringValine boolValineAppid stringValineAppkey stringValineServerURL string
}
models/category.go
package modelstype Category struct {Cid intName stringCreateAt stringUpdateAt string
}
models/post.go
package modelsimport ("goblog/config""html/template""time"
)type Post struct {Pid int `json:"pid"` // 文章IDTitle string `json:"title"` // 文章IDSlug string `json:"slug"` // 自定也頁面 pathContent string `json:"content"` // 文章的htmlMarkdown string `json:"markdown"` // 文章的MarkdownCategoryId int `json:"categoryId"` //分類idUserId int `json:"userId"` //用戶idViewCount int `json:"viewCount"` //查看次數Type int `json:"type"` //文章類型 0 普通,1 自定義文章CreateAt time.Time `json:"createAt"` // 創建時間UpdateAt time.Time `json:"updateAt"` // 更新時間
}type PostMore struct {Pid int `json:"pid"` // 文章IDTitle string `json:"title"` // 文章IDSlug string `json:"slug"` // 自定也頁面 pathContent template.HTML `json:"content"` // 文章的htmlCategoryId int `json:"categoryId"` // 文章的MarkdownCategoryName string `json:"categoryName"` // 分類名UserId int `json:"userId"` // 用戶idUserName string `json:"userName"` // 用戶名ViewCount int `json:"viewCount"` // 查看次數Type int `json:"type"` // 文章類型 0 普通,1 自定義文章CreateAt string `json:"createAt"`UpdateAt string `json:"updateAt"`
}type PostReq struct {Pid int `json:"pid"`Title string `json:"title"`Slug string `json:"slug"`Content string `json:"content"`Markdown string `json:"markdown"`CategoryId int `json:"categoryId"`UserId int `json:"userId"`Type int `json:"type"`
}type SearchResp struct {Pid int `orm:"pid" json:"pid"` // 文章IDTitle string `orm:"title" json:"title"`
}type PostRes struct {config.Viewerconfig.SystemConfigArticle PostMore
}
models/home.go
package modelstype HomeData struct {config.ViewerCategorys []CategoryPosts []PostMoreTotal intPage intPages []intPageEnd bool
}
4. 配置文件讀取
config.toml:
[viewer]Title = "碼神之路Go語言博客"Description = "碼神之路Go語言博客"Logo = "/resource/images/logo.png"Navigation = ["首頁","/", "GO語言","/golang", "歸檔","/pigeonhole", "關于","/about"]Bilibili = "https://space.bilibili.com/473844125"Zhihu = "https://www.zhihu.com/people/ma-shen-zhi-lu"Avatar = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13147603927%2F1000.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1647242040&t=c6108010ed46b4acebe18955acdd2d24"UserName = "碼神之路"UserDesc = "長得非常帥的程序員"
[system]CdnURL = "https://static.mszlu.com/goblog/es6/md-assets"QiniuAccessKey = "替換自己的"QiniuSecretKey = "替換自己的"Valine = trueValineAppid = "替換自己的"ValineAppkey = "替換自己的"ValineServerURL = "替換自己的"
package configimport ("github.com/BurntSushi/toml""os"
)type TomlConfig struct {Viewer ViewerSystem SystemConfig
}
type Viewer struct {Title stringDescription stringLogo stringNavigation []stringBilibili stringAvatar stringUserName stringUserDesc string
}
type SystemConfig struct {AppName stringVersion float32CurrentDir stringCdnURL stringQiniuAccessKey stringQiniuSecretKey stringValine boolValineAppid stringValineAppkey stringValineServerURL string
}
var Cfg *TomlConfigfunc init() {Cfg = new(TomlConfig)var err errorCfg.System.CurrentDir, err = os.Getwd()if err != nil {panic(err)}Cfg.System.AppName = "mszlu-go-blog"Cfg.System.Version = 1.0_,err = toml.DecodeFile("config/config.toml",&Cfg)if err != nil {panic(err)}
}
5. 假數據-顯示首頁內容
package mainimport ("html/template""log""ms-go-blog/config""ms-go-blog/models""net/http""time"
)type IndexData struct {Title string `json:"title"`Desc string `json:"desc"`
}func IsODD(num int) bool {return num%2 == 0
}
func GetNextName(strs []string,index int) string{return strs[index+1]
}
func Date(layout string) string{return time.Now().Format(layout)
}
func index(w http.ResponseWriter,r *http.Request) {t := template.New("index.html")//1. 拿到當前的路徑path := config.Cfg.System.CurrentDir//訪問博客首頁模板的時候,因為有多個模板的嵌套,解析文件的時候,需要將其涉及到的所有模板都進行解析home := path + "/template/home.html"header := path + "/template/layout/header.html"footer := path + "/template/layout/footer.html"personal := path + "/template/layout/personal.html"post := path + "/template/layout/post-list.html"pagination := path + "/template/layout/pagination.html"t.Funcs(template.FuncMap{"isODD":IsODD,"getNextName":GetNextName,"date":Date})t,err := t.ParseFiles(path + "/template/index.html",home,header,footer,personal,post,pagination)if err != nil {log.Println(err)}//頁面上涉及到的所有的數據,必須有定義var categorys = []models.Category{{Cid: 1,Name: "go",},}var posts = []models.PostMore{{Pid: 1,Title: "go博客",Content: "內容",UserName: "碼神",ViewCount: 123,CreateAt: "2022-02-20",CategoryId:1,CategoryName: "go",Type:0,},}var hr = &models.HomeResponse{config.Cfg.Viewer,categorys,posts,1,1,[]int{1},true,}t.Execute(w,hr)
}func main() {//程序入口,一個項目 只能有一個入口//web程序,http協議 ip portserver := http.Server{Addr: "127.0.0.1:8080",}http.HandleFunc("/",index)http.Handle("/resource/",http.StripPrefix("/resource/",http.FileServer(http.Dir("public/resource/"))))if err := server.ListenAndServe();err != nil{log.Println(err)}
}
后續內容在gitee上面: 傳送門
記得給一個start 啊
使用 : 直接克隆地址到自己的go項目中,瀏覽器訪問 127.0.0.1:8080可訪問