在学习 Go 的过程中,构建一个简易博客系统 是非常典型的练手项目。通过这个项目,我们不仅能掌握 Web 开发的基本流程,还能实现文章发布、浏览、评论互动等核心功能。本文将带你实现一个基于 Go 的简易博客系统,并逐步扩展到支持评论功能。
功能目标
-
文章管理
- 发布文章(标题、内容)
- 查看文章列表
- 查看文章详情
-
评论功能
- 在文章下添加评论
- 展示评论列表
-
存储方式
- 使用内存存储(map/切片)实现简单版本
- 后续可扩展为文件存储或数据库
技术栈
- Go 标准库 :
net/http
、html/template
- 模板渲染:动态生成 HTML 页面
- 数据存储:使用结构体和切片模拟数据库
项目结构
csharp
blog/
├── main.go # 入口
├── templates/
│ ├── index.html # 首页文章列表
│ ├── view.html # 文章详情(含评论)
│ └── new.html # 新建文章
核心代码(main.go)
go
package main
import (
"html/template"
"net/http"
"strconv"
"sync"
)
// 文章结构体
type Post struct {
ID int
Title string
Content string
Comments []Comment
}
// 评论结构体
type Comment struct {
Author string
Content string
}
// 模拟数据库
var (
posts = make(map[int]*Post)
idSeq = 1
mu sync.Mutex
)
func main() {
http.HandleFunc("/", listPosts)
http.HandleFunc("/post", viewPost)
http.HandleFunc("/new", newPost)
http.HandleFunc("/save", savePost)
http.HandleFunc("/comment", addComment)
http.ListenAndServe(":8080", nil)
}
// 列出所有文章
func listPosts(w http.ResponseWriter, r *http.Request) {
tpl := template.Must(template.ParseFiles("templates/index.html"))
tpl.Execute(w, posts)
}
// 查看文章详情
func viewPost(w http.ResponseWriter, r *http.Request) {
id, _ := strconv.Atoi(r.URL.Query().Get("id"))
post, ok := posts[id]
if !ok {
http.NotFound(w, r)
return
}
tpl := template.Must(template.ParseFiles("templates/view.html"))
tpl.Execute(w, post)
}
// 新建文章页面
func newPost(w http.ResponseWriter, r *http.Request) {
tpl := template.Must(template.ParseFiles("templates/new.html"))
tpl.Execute(w, nil)
}
// 保存文章
func savePost(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
mu.Lock()
defer mu.Unlock()
post := &Post{
ID: idSeq,
Title: r.FormValue("title"),
Content: r.FormValue("content"),
}
posts[idSeq] = post
idSeq++
http.Redirect(w, r, "/", http.StatusSeeOther)
}
// 添加评论
func addComment(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
id, _ := strconv.Atoi(r.FormValue("id"))
post, ok := posts[id]
if !ok {
http.NotFound(w, r)
return
}
comment := Comment{
Author: r.FormValue("author"),
Content: r.FormValue("content"),
}
post.Comments = append(post.Comments, comment)
http.Redirect(w, r, "/post?id="+strconv.Itoa(id), http.StatusSeeOther)
}
模板文件
index.html
html
<h1>文章列表</h1>
<a href="/new">写新文章</a>
<ul>
{{range .}}
<li><a href="/post?id={{.ID}}">{{.Title}}</a></li>
{{end}}
</ul>
new.html
html
<h1>写新文章</h1>
<form action="/save" method="post">
标题: <input type="text" name="title"><br>
内容: <textarea name="content"></textarea><br>
<button type="submit">发布</button>
</form>
view.html
html
<h1>{{.Title}}</h1>
<p>{{.Content}}</p>
<h2>评论</h2>
<ul>
{{range .Comments}}
<li><b>{{.Author}}</b>: {{.Content}}</li>
{{end}}
</ul>
<form action="/comment" method="post">
<input type="hidden" name="id" value="{{.ID}}">
昵称: <input type="text" name="author"><br>
评论: <textarea name="content"></textarea><br>
<button type="submit">提交评论</button>
</form>
运行效果
- 启动服务:
bash
go run main.go
- 首页显示文章列表
- 可以发布新文章
- 点击文章进入详情页,支持评论功能
总结与扩展
我们实现了一个简易博客系统,包括文章的增/查和评论功能,数据存储在内存中。
可扩展的方向:
- 使用 文件存储 或 SQLite/MySQL 保存数据
- 添加 用户系统(注册/登录/权限)
- 评论支持 时间戳、回复、点赞
- 前端引入 Bootstrap/Vue.js 优化页面
通过这个项目,你不仅能加深对 net/http
和模板渲染的理解,还能体验到 Web 应用开发的完整流程,是 Go 学习过程中非常经典的一个实战案例。