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), PageValidationMiddleware(s), func(c *gin.Context) { pageNumber, _ := c.Get("pageNumber") page := models.NewPage(s, s.Posts, pageNumber.(int), AccessLvl(c), "") data, err := getPageByName(s, page, tmplname) if err != nil { c.String(http.StatusInternalServerError, "Ошибка рендеринга: %v", err) return } sendPage(c, data) }) } // Вынесенный общий код для получения страницы func getPageByName( s *models.Site, page *models.Page, tmplname string) (string, error) { var data string var err error if page.AccessLvl != 0 { // Для админа - рендер без кэширования data, err = page.RenderPage(s, tmplname) } else { key := fmt.Sprintf("%s%d", tmplname, page.Number) // Попытка получить страницу из кэша if cachedData, err := s.Cache.Get(key); err == nil { data = cachedData.(string) } else { // Нет в кэше => рендерим data, err = page.RenderPage(s, tmplname) if err == nil { // Сжимаю по возможности и добавляю в кэш go func() { compressedData, err := tools.MinifyStringHtml(data) if err != nil { s.Cache.Set(key, data, -1) } else { s.Cache.Set(key, compressedData, -1) } }() } } } return data, err } func SearchPage(tmplname string, group *gin.RouterGroup, s *models.Site) { 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) // Валидная страничка, рендерим data, err := getSearchPage(s, page, tmplname) if err != nil { c.String(http.StatusInternalServerError, "Ошибка рендеринга: %v", err) return } sendPage(c, data) }) } // Вынесенный общий код func getSearchPage( s *models.Site, page *models.Page, tmplname string) (string, error) { var data string var err error // Для админа - рендер без кэширования 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, page.Number, page.Data) if cachedData, err := s.Cache.Get(key); err == nil { data = cachedData.(string) } else { // Нет в кэше => рендерим page.PostsSublist = s.Posts.GetPostListBySubstring(page.Data) data, err = page.RenderPage(s, tmplname) // если нет ошибки и список постов не пустой, то надо добавить в кэш if err == nil && len(page.PostsSublist) > 0 { // Сжимаю по возможности и добавляю в кэш go func() { compressedData, err := tools.MinifyStringHtml(data) if err != nil { s.Cache.Set(key, data, -1) } else { s.Cache.Set(key, compressedData, -1) } }() } } } return data, err } func sendPage(c *gin.Context, data string) { c.Header("Content-Type", "text/html; charset=utf-8") c.String(http.StatusOK, data) }