携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
项目原视频地址:www.bilibili.com/video/BV1VS…
html + css 地址:www.mszlu.com/
练手级项目教程,使用原生Go开发。
路由处理与封装📦
blog-go/router/router.go
package router
import (
"blog-go/api"
"blog-go/views"
"net/http"
)
func Router() {
// HTML
http.HandleFunc("/", views.HTML.Index)
// 数据 API
http.HandleFunc("/api/v1/post", api.API.SaveAndUpdatePost)
http.Handle("/resource/", http.StripPrefix("/resource/", http.FileServer(http.Dir("public/resource/"))))
}
api 文件下存放 API 数据
blog-go/api
package api
var API = &Api{}
type Api struct {
}
blog-go/api/post.go
package api
import "net/http"
func (*Api) SaveAndUpdatePost(w http.ResponseWriter, r *http.Request) {
}
这个样子,当我们需要新增接口的时候,只需要在 api 文件夹下新增文件即可。
初始化模板加载
blog-go/main.go
package main
import (
"blog-go/common"
"blog-go/router"
"log"
"net/http"
)
func init() {
// 初始化模板加载
common.LoadTemplate()
}
func main() {
server := http.Server{
Addr: "127.0.0.1:8085",
}
router.Router()
if err := server.ListenAndServe(); err != nil {
log.Println(err)
}
}
WaitGroup主要用于同步多个协程间的状态(例如等待所有协程都执行完)。在WaitGroup 对象实现中,内部有一个计数器,最初从0开始,它有三个方法:
Add():计数器加一Done():计数器减一Wait():等待计数器清零
执行Wait方法的函数在等待组内部计数器不为0的时候回阻塞,一旦计数器为0了,程序就会继续往下执行。
blog-go/common/common.go
package common
import (
"blog-go/config"
"blog-go/models"
"sync"
)
var Template models.HtmlTemplate
func LoadTemplate() {
w := sync.WaitGroup{}
w.Add(1)
go func() {
Template = models.InitTemplate(config.Cfg.System.CurrentDir + "/template/")
w.Done()
}()
w.Wait()
}
blog-go/models/template.go
func InitTemplate(templateDir string) HtmlTemplate {
tp := readTemplate(
[]string{"index", "category", "custom", "detail", "login", "pigeonhole", "writing"},
templateDir,
)
}
readTemplate 函数,将之前解析 html 的函数进行封装,传入 template 下 html 的名称,即可解析 html。
func readTemplate(templates []string, templateDir string) []TemplateBlog {
var tbs []TemplateBlog
for _, view := range templates {
viewName := view + ".html"
t := template.New(viewName)
indexHtml := templateDir + "index.html"
home := templateDir + "home.html"
head := templateDir + "layout/header.html"
footer := templateDir + "layout/footer.html"
personal := templateDir + "layout/personal.html"
post := templateDir + "layout/post-list.html"
pagination := templateDir + "layout/pagination.html"
t.Funcs(template.FuncMap{"isODD": IsODD, "getNextName": GetNextName, "date": Date})
t, err := t.ParseFiles(indexHtml, home, head, footer, personal, post, pagination)
if err != nil {
log.Println(err)
}
var tb TemplateBlog
tb.Template = t
tbs = append(tbs, tb)
}
return tbs
}
回到 InitTemplate 函数。将处理好的值赋值给 htmlTemplate。
type TemplateBlog struct {
*template.Template
}
type HtmlTemplate struct {
Index TemplateBlog
Category TemplateBlog
Custom TemplateBlog
Detail TemplateBlog
Login TemplateBlog
Pigeonhole TemplateBlog
Writing TemplateBlog
}
func InitTemplate(templateDir string) HtmlTemplate {
//....
var htmlTemplate HtmlTemplate
htmlTemplate.Index = tp[0]
htmlTemplate.Category = tp[1]
htmlTemplate.Custom = tp[2]
htmlTemplate.Detail = tp[3]
htmlTemplate.Login = tp[4]
htmlTemplate.Pigeonhole = tp[5]
htmlTemplate.Writing = tp[6]
return htmlTemplate
}
blog-go/views/index.go
假数据的写入
package views
import (
"blog-go/common"
"blog-go/config"
"blog-go/models"
"html/template"
"net/http"
)
func (*HTMLApi) Index(w http.ResponseWriter, r *http.Request) {
index := common.Template.Index
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 homeData = &models.HomeResponse{
Viewer: config.Cfg.Viewer,
Categorys: categorys,
Posts: posts,
Total: 1,
Pages: []int{1},
PageEnd: true,
}
index.WriteData(w, homeData)
t := template.New("index.html")
t.Execute(w, homeData)
}
刷新页面,页面一切正常。