78 lines
2.1 KiB
Go
78 lines
2.1 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"go_blog/models"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// publishedArticleOrder is the ordering used to list published articles:
|
|
// pinned first, then by most recent publish/creation time.
|
|
const publishedArticleOrder = "is_top DESC, published_at DESC, created_at DESC"
|
|
|
|
// HomePage renders the public home page with the latest published articles.
|
|
func HomePage(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
tr := getTr(c)
|
|
data := DefaultData(c)
|
|
data["Title"] = tr["page_home"]
|
|
|
|
var articles []models.Article
|
|
db.Where("status = ?", models.ArticlePublished).
|
|
Order(publishedArticleOrder).
|
|
Limit(10).
|
|
Find(&articles)
|
|
data["Articles"] = articles
|
|
|
|
c.HTML(http.StatusOK, "home", data)
|
|
}
|
|
}
|
|
|
|
// ArticleDetail renders a single published article by its slug.
|
|
func ArticleDetail(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
tr := getTr(c)
|
|
slug := c.Param("slug")
|
|
|
|
var article models.Article
|
|
err := db.Where("slug = ? AND status = ?", slug, models.ArticlePublished).
|
|
Preload("Author").
|
|
First(&article).Error
|
|
if err != nil {
|
|
data := DefaultData(c)
|
|
data["Title"] = tr["article_not_found"]
|
|
c.HTML(http.StatusNotFound, "article_not_found", data)
|
|
return
|
|
}
|
|
|
|
// Increment view count; ignore errors so a view never breaks the page.
|
|
db.Model(&models.Article{}).Where("id = ?", article.ID).
|
|
UpdateColumn("view_count", gorm.Expr("view_count + 1"))
|
|
|
|
authorName := article.Author.Username
|
|
if article.Author.DisplayName != "" {
|
|
authorName = article.Author.DisplayName
|
|
}
|
|
|
|
data := DefaultData(c)
|
|
data["Title"] = article.Title
|
|
data["Article"] = article
|
|
data["AuthorName"] = authorName
|
|
data["PublishedAt"] = formatPublishTime(article.PublishedAt)
|
|
c.HTML(http.StatusOK, "article", data)
|
|
}
|
|
}
|
|
|
|
// formatPublishTime returns the publication time as a readable string, falling
|
|
// back to the creation time when the publish timestamp is unset.
|
|
func formatPublishTime(publishedAt *time.Time) string {
|
|
if publishedAt != nil {
|
|
return publishedAt.Format("2006-01-02 15:04")
|
|
}
|
|
return ""
|
|
}
|