hikan.ru/mvc/controllers/page.go

137 lines
3.8 KiB
Go
Raw Normal View History

2025-02-02 16:43:55 +03:00
package controllers
import (
"fmt"
"main/mvc/models"
"main/tools"
"net/http"
"github.com/gin-gonic/gin"
)
// Задает маршруты для страниц вида tmplname/id.html, где необходим список всех постов
func PageByName(tmplname string, group *gin.RouterGroup, s *models.Site) {
group.GET(
fmt.Sprintf("/%s/:id", tmplname),
2025-02-02 16:43:55 +03:00
PageValidationMiddleware(s),
func(c *gin.Context) {
pageNumber, _ := c.Get("pageNumber")
page := models.NewPage(s, s.Posts, pageNumber.(int), AccessLvl(c), "")
2025-02-02 16:43:55 +03:00
data, err := getPageByName(s, page, tmplname)
2025-02-02 16:43:55 +03:00
if err != nil {
c.String(http.StatusInternalServerError, "Ошибка рендеринга: %v", err)
return
}
sendPage(c, data)
2025-02-02 16:43:55 +03:00
})
}
// Вынесенный общий код для получения страницы
func getPageByName(
s *models.Site,
page *models.Page,
tmplname string) (string, error) {
2025-02-02 16:43:55 +03:00
var data string
2025-02-02 16:43:55 +03:00
var err error
if page.AccessLvl != 0 {
2025-02-02 16:43:55 +03:00
// Для админа - рендер без кэширования
data, err = page.RenderPage(s, tmplname)
2025-02-02 16:43:55 +03:00
} else {
key := fmt.Sprintf("%s%d", tmplname, page.Number)
2025-02-02 16:43:55 +03:00
// Попытка получить страницу из кэша
if cachedData, err := s.Cache.Get(key); err == nil {
data = cachedData.(string)
2025-02-02 16:43:55 +03:00
} else {
// Нет в кэше => рендерим
data, err = page.RenderPage(s, tmplname)
2025-02-02 16:43:55 +03:00
if err == nil {
// Сжимаю по возможности и добавляю в кэш
go func() {
compressedData, err := tools.MinifyStringHtml(data)
2025-02-02 16:43:55 +03:00
if err != nil {
s.Cache.Set(key, data, -1)
2025-02-02 16:43:55 +03:00
} else {
s.Cache.Set(key, compressedData, -1)
2025-02-02 16:43:55 +03:00
}
}()
}
}
}
return data, err
2025-02-02 16:43:55 +03:00
}
func SearchPage(tmplname string, group *gin.RouterGroup, s *models.Site) {
group.GET(
fmt.Sprintf("/%s/:id", tmplname),
2025-02-02 16:43:55 +03:00
PageValidationMiddleware(s),
func(c *gin.Context) {
searchSubstring := c.Query("search")
pageNumber, _ := c.Get("pageNumber")
// на этом этапе postsSublist = nil, он должен
// быть сформирован в getSearchPage
page := models.NewPage(s, nil, pageNumber.(int), AccessLvl(c), searchSubstring)
2025-02-02 16:43:55 +03:00
// Валидная страничка, рендерим
data, err := getSearchPage(s, page, tmplname)
2025-02-02 16:43:55 +03:00
if err != nil {
c.String(http.StatusInternalServerError, "Ошибка рендеринга: %v", err)
return
}
sendPage(c, data)
2025-02-02 16:43:55 +03:00
})
}
// Вынесенный общий код
func getSearchPage(
s *models.Site,
page *models.Page,
tmplname string) (string, error) {
2025-02-02 16:43:55 +03:00
var data string
2025-02-02 16:43:55 +03:00
var err error
// Для админа - рендер без кэширования
if page.AccessLvl != 0 {
// посты, содержащие искомую подстроку
page.PostsSublist = s.Posts.GetPostListBySubstring(page.Data)
data, err = page.RenderPage(s, tmplname)
2025-02-02 16:43:55 +03:00
} else {
key := fmt.Sprintf("%s%d%s", tmplname, page.Number, page.Data)
2025-02-02 16:43:55 +03:00
if cachedData, err := s.Cache.Get(key); err == nil {
data = cachedData.(string)
2025-02-02 16:43:55 +03:00
} else {
// Нет в кэше => рендерим
page.PostsSublist = s.Posts.GetPostListBySubstring(page.Data)
data, err = page.RenderPage(s, tmplname)
2025-02-02 16:43:55 +03:00
// если нет ошибки и список постов не пустой, то надо добавить в кэш
if err == nil && len(page.PostsSublist) > 0 {
2025-02-02 16:43:55 +03:00
// Сжимаю по возможности и добавляю в кэш
go func() {
compressedData, err := tools.MinifyStringHtml(data)
2025-02-02 16:43:55 +03:00
if err != nil {
s.Cache.Set(key, data, -1)
2025-02-02 16:43:55 +03:00
} else {
s.Cache.Set(key, compressedData, -1)
2025-02-02 16:43:55 +03:00
}
}()
}
}
}
return data, err
2025-02-02 16:43:55 +03:00
}
func sendPage(c *gin.Context, data string) {
2025-02-02 16:43:55 +03:00
c.Header("Content-Type", "text/html; charset=utf-8")
c.String(http.StatusOK, data)
2025-02-02 16:43:55 +03:00
}