Files
go_blog/handlers/article.go
T
2026-06-21 19:29:42 +08:00

136 lines
3.4 KiB
Go

package handlers
import (
"net/http"
"regexp"
"strings"
"time"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"go_blog/models"
"gorm.io/gorm"
)
// slugRe matches characters that are not URL-safe.
var slugRe = regexp.MustCompile(`[^a-z0-9\-]+`)
// generateSlug converts a title into a URL-friendly slug.
func generateSlug(title string) string {
s := strings.ToLower(title)
s = strings.ReplaceAll(s, " ", "-")
s = slugRe.ReplaceAllString(s, "")
s = strings.Trim(s, "-")
// Collapse multiple dashes.
s = regexp.MustCompile(`-{2,}`).ReplaceAllString(s, "-")
return s
}
// ArticleCreatePage renders the article creation form.
func ArticleCreatePage(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
tr := getTr(c)
data := DefaultData(c)
data["Title"] = tr["article_create_title"]
c.HTML(http.StatusOK, "article_create", data)
}
}
// ArticleCreate handles the POST request to create a new article.
func ArticleCreate(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
tr := getTr(c)
title := strings.TrimSpace(c.PostForm("title"))
content := strings.TrimSpace(c.PostForm("content"))
slug := strings.TrimSpace(c.PostForm("slug"))
summary := strings.TrimSpace(c.PostForm("summary"))
cover := strings.TrimSpace(c.PostForm("cover"))
statusStr := c.PostForm("status")
isTop := c.PostForm("is_top") == "1"
// Validate required fields.
if title == "" {
data := DefaultData(c)
data["Title"] = tr["article_create_title"]
data["Error"] = tr["article_title_required"]
data["FormTitle"] = title
data["FormSlug"] = slug
data["FormSummary"] = summary
data["FormContent"] = content
data["FormCover"] = cover
data["FormStatus"] = statusStr
c.HTML(http.StatusOK, "article_create", data)
return
}
if content == "" {
data := DefaultData(c)
data["Title"] = tr["article_create_title"]
data["Error"] = tr["article_content_required"]
data["FormTitle"] = title
data["FormSlug"] = slug
data["FormSummary"] = summary
data["FormContent"] = content
data["FormCover"] = cover
data["FormStatus"] = statusStr
c.HTML(http.StatusOK, "article_create", data)
return
}
// Auto-generate slug if empty.
if slug == "" {
slug = generateSlug(title)
}
// Parse status: default to draft (0).
status := models.ArticleDraft
if statusStr == "1" {
status = models.ArticlePublished
}
// Get author ID from session.
session := sessions.Default(c)
userID := session.Get("user_id")
if userID == nil {
c.Redirect(http.StatusFound, "/login")
return
}
var publishedAt *time.Time
if status == models.ArticlePublished {
now := time.Now()
publishedAt = &now
}
article := models.Article{
AuthorID: uint(userID.(int)),
Title: title,
Slug: slug,
Summary: summary,
Content: content,
Cover: cover,
Status: status,
IsTop: isTop,
PublishedAt: publishedAt,
}
if err := db.Create(&article).Error; err != nil {
data := DefaultData(c)
data["Title"] = tr["article_create_title"]
data["Error"] = tr["article_error"]
data["FormTitle"] = title
data["FormSlug"] = slug
data["FormSummary"] = summary
data["FormContent"] = content
data["FormCover"] = cover
data["FormStatus"] = statusStr
c.HTML(http.StatusOK, "article_create", data)
return
}
// Success: redirect to dashboard.
c.Redirect(http.StatusFound, "/admin")
}
}