article.go 1.8 KB

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