article.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package handler
  2. import (
  3. "database/sql"
  4. "github.com/dmitriygnatenko/internal/interfaces"
  5. "github.com/dmitriygnatenko/internal/mapper"
  6. "github.com/gofiber/fiber/v2"
  7. )
  8. const (
  9. maxArticlesCount = 3
  10. articleParam = "article"
  11. articleCacheKey = "article"
  12. )
  13. func ArticleHandler(sp interfaces.ServiceProvider) fiber.Handler {
  14. return func(ctx *fiber.Ctx) error {
  15. articleReq := ctx.Params(articleParam)
  16. renderData, found := sp.GetCacheService().Get(articleCacheKey + articleReq)
  17. if !found {
  18. article, err := sp.GetArticleRepository().GetByURL(ctx.Context(), articleReq)
  19. if err != nil {
  20. if err == sql.ErrNoRows {
  21. return fiber.ErrNotFound
  22. }
  23. return err
  24. }
  25. if !article.IsActive {
  26. return fiber.ErrNotFound
  27. }
  28. articleDTO, err := mapper.ConvertArticleModelToDTO(*article)
  29. if err != nil {
  30. return err
  31. }
  32. // All used tags
  33. tags, err := sp.GetTagRepository().GetAllUsed(ctx.Context())
  34. if err != nil {
  35. return err
  36. }
  37. tagsDTO := mapper.ConvertTagModelsToDTO(tags)
  38. // Last articles
  39. articles, err := sp.GetArticleRepository().GetAllPreview(ctx.Context())
  40. if err != nil {
  41. return err
  42. }
  43. if len(articles) > maxArticlesCount {
  44. articles = articles[:maxArticlesCount]
  45. }
  46. articlesDTO, err := mapper.ConvertArticlePreviewModelsToDTO(articles)
  47. if err != nil {
  48. return err
  49. }
  50. renderData = fiber.Map{
  51. "headTitle": "От слона к суслику - статьи про PHP, Go, алгоритмы",
  52. "headDescription": articleDTO.MetaDescription,
  53. "headKeywords": articleDTO.MetaKeywords,
  54. "pageTitle": "Статья<br>" + articleDTO.Title,
  55. "article": articleDTO,
  56. "sidebarArticles": articlesDTO,
  57. "sidebarTags": tagsDTO,
  58. }
  59. sp.GetCacheService().Set(articleCacheKey+articleReq, renderData)
  60. }
  61. return ctx.Render("article", renderData, "_layout")
  62. }
  63. }