From 959d0532bd763486e65df11f74e2747157d72fa7 Mon Sep 17 00:00:00 2001 From: serr Date: Mon, 3 Feb 2025 12:11:13 +0300 Subject: [PATCH] =?UTF-8?q?renderpage()=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BB=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=BE=D0=BC=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20Page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mvc/controllers/page.go | 110 +++++++++++++++++++--------------------- mvc/models/page.go | 20 ++++++++ 2 files changed, 71 insertions(+), 59 deletions(-) diff --git a/mvc/controllers/page.go b/mvc/controllers/page.go index 041db4f..61bbf50 100644 --- a/mvc/controllers/page.go +++ b/mvc/controllers/page.go @@ -1,7 +1,6 @@ package controllers import ( - "bytes" "fmt" "main/mvc/models" "main/tools" @@ -12,133 +11,126 @@ import ( // Задает маршруты для страниц вида tmplname/id.html, где необходим список всех постов 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), func(c *gin.Context) { 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 { c.String(http.StatusInternalServerError, "Ошибка рендеринга: %v", err) return } - sendPage(c, page) + sendPage(c, data) }) } // Вынесенный общий код для получения страницы -func getPageByName(c *gin.Context, s *models.Site, tmplname string, - pageNumber int, pageContext *models.Page) (string, error) { +func getPageByName( + s *models.Site, + page *models.Page, + tmplname string) (string, error) { - var page string + var data string var err error - if AccessLvl(c) != 0 { + if page.AccessLvl != 0 { // Для админа - рендер без кэширования - page, err = RenderPage(pageContext, tmplname, s) + data, err = page.RenderPage(s, tmplname) } 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 { - page = cachedPage.(string) + if cachedData, err := s.Cache.Get(key); err == nil { + data = cachedData.(string) } else { // Нет в кэше => рендерим - page, err = RenderPage(pageContext, tmplname, s) + data, err = page.RenderPage(s, tmplname) if err == nil { // Сжимаю по возможности и добавляю в кэш go func() { - compressedPage, err := tools.MinifyStringHtml(page) + compressedData, err := tools.MinifyStringHtml(data) if err != nil { - s.Cache.Set(key, page, -1) + s.Cache.Set(key, data, -1) } 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) { - group.GET(fmt.Sprintf("/%s/:id", tmplname), + + group.GET( + fmt.Sprintf("/%s/:id", tmplname), 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) // Валидная страничка, рендерим - page, err := getSearchPage(c, s, tmplname, pageNumber.(int), searchSubstring) + data, err := getSearchPage(s, page, tmplname) if err != nil { c.String(http.StatusInternalServerError, "Ошибка рендеринга: %v", err) return } - sendPage(c, page) + sendPage(c, data) }) } // Вынесенный общий код -func getSearchPage(c *gin.Context, s *models.Site, tmplname string, - pageNumber int, searchSubstring string) (string, error) { +func getSearchPage( + s *models.Site, + page *models.Page, + tmplname string) (string, error) { - var page string + var data string var err error - - if AccessLvl(c) != 0 { // кэширую только странички по тегам - // Для админа - рендер без кэширования - posts := s.Posts.GetPostListBySubstring(searchSubstring) // посты, содержащие искомую подстроку - pageContext := models.NewPage(s, posts, pageNumber, AccessLvl(c), searchSubstring) - page, err = RenderPage(pageContext, tmplname, s) + // Для админа - рендер без кэширования + if page.AccessLvl != 0 { + // посты, содержащие искомую подстроку + page.PostsSublist = s.Posts.GetPostListBySubstring(page.Data) + data, err = page.RenderPage(s, tmplname) } 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 { - page = cachedPage.(string) + if cachedData, err := s.Cache.Get(key); err == nil { + data = cachedData.(string) } else { // Нет в кэше => рендерим - posts := s.Posts.GetPostListBySubstring(searchSubstring) - pageContext := models.NewPage(s, posts, pageNumber, AccessLvl(c), searchSubstring) - page, err = RenderPage(pageContext, tmplname, s) + page.PostsSublist = s.Posts.GetPostListBySubstring(page.Data) + data, err = page.RenderPage(s, tmplname) // если нет ошибки и список постов не пустой, то надо добавить в кэш - if err == nil && len(posts) > 0 { + if err == nil && len(page.PostsSublist) > 0 { // Сжимаю по возможности и добавляю в кэш go func() { - compressedPage, err := tools.MinifyStringHtml(page) + compressedData, err := tools.MinifyStringHtml(data) if err != nil { - s.Cache.Set(key, page, -1) + s.Cache.Set(key, data, -1) } else { - s.Cache.Set(key, compressedPage, -1) + s.Cache.Set(key, compressedData, -1) } }() } } } - return page, err + return data, err } -func RenderPage(pageContext *models.Page, - 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) { +func sendPage(c *gin.Context, data string) { c.Header("Content-Type", "text/html; charset=utf-8") - c.String(http.StatusOK, page) + c.String(http.StatusOK, data) } diff --git a/mvc/models/page.go b/mvc/models/page.go index 428452a..3ace66a 100644 --- a/mvc/models/page.go +++ b/mvc/models/page.go @@ -1,5 +1,10 @@ package models +import ( + "bytes" + "fmt" +) + // Контекст страницы type Page struct { 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 +}