123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- package handler
- import (
- "database/sql"
- "errors"
- "git.dmitriygnatenko.ru/dima/go-common/logger"
- "github.com/gofiber/fiber/v2"
- "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/dto"
- "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/mapper"
- "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/services/i18n"
- )
- const (
- ArticleCacheKey = "article"
- RecentArticlesCacheKey = "recent-articles"
- UsedTagsCacheKey = "used-tags"
- previewArticlesCount = 3
- articleParam = "article"
- )
- func ArticleHandler(
- cacheService CacheService,
- articleRepository ArticleRepository,
- tagRepository TagRepository,
- ) fiber.Handler {
- return func(fctx *fiber.Ctx) error {
- var renderData fiber.Map
- ctx := fctx.Context()
- url := fctx.Params(articleParam)
- lang := mapper.LanguageFromContext(fctx)
- // article
- articleCacheKey := ArticleCacheKey + url
- cacheData, found := cacheService.Get(articleCacheKey)
- if found {
- if articleData, ok := cacheData.(fiber.Map); ok {
- renderData = articleData
- }
- }
- if renderData == nil {
- article, err := articleRepository.GetByURL(ctx, url, mapper.ToLanguageModel(lang))
- if err != nil {
- logger.Error(ctx, err.Error())
- if errors.Is(err, sql.ErrNoRows) {
- return fiber.ErrNotFound
- }
- logger.Error(ctx, err.Error())
- return err
- }
- if !article.IsActive {
- return fiber.ErrNotFound
- }
- articleDTO := mapper.ToArticle(lang, *article)
- renderData = fiber.Map{
- "lang": lang,
- "headTitle": i18n.T(lang, "head_title"),
- "headDescription": articleDTO.MetaDescription,
- "headKeywords": articleDTO.MetaKeywords,
- "pageTitle": i18n.T(lang, "article_page_title", articleDTO.Title),
- "article": articleDTO,
- }
- cacheService.Set(articleCacheKey, renderData, nil)
- }
- // recent articles
- recentArticlesCacheKey := RecentArticlesCacheKey + string(lang)
- cacheData, found = cacheService.Get(recentArticlesCacheKey)
- if found {
- if articlesData, ok := cacheData.([]dto.ArticlePreview); ok {
- renderData["sidebarArticles"] = articlesData
- }
- }
- if _, ok := renderData["sidebarArticles"]; !ok {
- articles, err := articleRepository.GetAllPreview(ctx, mapper.ToLanguageModel(lang))
- if err != nil {
- logger.Error(ctx, err.Error())
- return err
- }
- if len(articles) > previewArticlesCount {
- articles = articles[:previewArticlesCount]
- }
- sidebarArticles := mapper.ToArticlesPreview(lang, articles)
- renderData["sidebarArticles"] = sidebarArticles
- cacheService.Set(recentArticlesCacheKey, sidebarArticles, nil)
- }
- // tags
- usedTagsCacheKey := UsedTagsCacheKey + string(lang)
- cacheData, found = cacheService.Get(usedTagsCacheKey)
- if found {
- if tagsData, ok := cacheData.([]dto.Tag); ok {
- renderData["sidebarTags"] = tagsData
- }
- }
- if _, ok := renderData["sidebarTags"]; !ok {
- tags, err := tagRepository.GetAllUsed(ctx, mapper.ToLanguageModel(lang))
- if err != nil {
- logger.Error(ctx, err.Error())
- return err
- }
- sidebarTags := mapper.ToTagsList(tags)
- renderData["sidebarTags"] = sidebarTags
- cacheService.Set(usedTagsCacheKey, sidebarTags, nil)
- }
- return fctx.Render("article", renderData, "_layout")
- }
- }
|