article.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package handler
  2. import (
  3. "database/sql"
  4. "errors"
  5. "git.dmitriygnatenko.ru/dima/go-common/logger"
  6. "github.com/gofiber/fiber/v2"
  7. "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/mapper"
  8. "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/services/i18n"
  9. )
  10. const (
  11. ArticleCacheKey = "article"
  12. maxArticlesCount = 3
  13. articleParam = "article"
  14. )
  15. func ArticleHandler(
  16. cacheService CacheService,
  17. articleRepository ArticleRepository,
  18. tagRepository TagRepository,
  19. ) fiber.Handler {
  20. return func(fctx *fiber.Ctx) error {
  21. ctx := fctx.Context()
  22. url := fctx.Params(articleParam)
  23. lang := i18n.Language(fctx)
  24. renderData, found := cacheService.Get(ArticleCacheKey + string(lang) + url)
  25. if !found {
  26. article, err := articleRepository.GetByURL(ctx, url)
  27. if err != nil {
  28. if errors.Is(err, sql.ErrNoRows) {
  29. return fiber.ErrNotFound
  30. }
  31. logger.Error(ctx, err.Error())
  32. return err
  33. }
  34. if !article.IsActive {
  35. return fiber.ErrNotFound
  36. }
  37. articleDTO := mapper.ToArticleDTO(fctx, *article)
  38. // All used tags
  39. tags, err := tagRepository.GetAllUsed(ctx)
  40. if err != nil {
  41. logger.Error(ctx, err.Error())
  42. return err
  43. }
  44. tagsDTO := mapper.ToTagDTOList(tags)
  45. // Last articles
  46. articles, err := articleRepository.GetAllPreview(ctx)
  47. if err != nil {
  48. logger.Error(ctx, err.Error())
  49. return err
  50. }
  51. if len(articles) > maxArticlesCount {
  52. articles = articles[:maxArticlesCount]
  53. }
  54. renderData = fiber.Map{
  55. "headTitle": i18n.T(lang, "head_title"),
  56. "headDescription": articleDTO.MetaDescription,
  57. "headKeywords": articleDTO.MetaKeywords,
  58. "pageTitle": i18n.T(lang, "article_page_title", articleDTO.Title),
  59. "article": articleDTO,
  60. "sidebarArticles": mapper.ToArticlePreviewDTOList(fctx, articles),
  61. "sidebarTags": tagsDTO,
  62. }
  63. cacheService.Set(ArticleCacheKey+string(lang)+url, renderData, nil)
  64. }
  65. return fctx.Render("article", renderData, "_layout")
  66. }
  67. }