renderpage() сделал методом для Page

master
serr 2025-02-03 12:11:13 +03:00
parent b00d917a60
commit 959d0532bd
2 changed files with 71 additions and 59 deletions

View File

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

View File

@ -1,5 +1,10 @@
package models package models
import (
"bytes"
"fmt"
)
// Контекст страницы // Контекст страницы
type Page struct { type Page struct {
AccessLvl int //уровень доступа юзера AccessLvl int //уровень доступа юзера
@ -25,3 +30,18 @@ func NewPage(s *Site, postsSublist Posts,
} }
} }
func (p *Page) RenderPage(s *Site, tmplname string) (string, error) {
var buffer bytes.Buffer
if err := s.Tmpl.ExecuteTemplate(
&buffer,
fmt.Sprintf("%s.gohtml", tmplname),
p); err != nil {
return "", err
}
return buffer.String(), nil
}