ContentList.hs 5.04 KB
Newer Older
1
2
3
4
module Site.Html.ContentList (
  contentListPage
  , renderPaginator
) where
Erik Aker's avatar
Erik Aker committed
5

6
import           Control.Lens
Erik Aker's avatar
Erik Aker committed
7
import qualified Data.Text                   as T
8
9
import           RIO                         hiding ((^.))
import qualified RIO.HashSet                 as HS
Erik Aker's avatar
Erik Aker committed
10
11
12
13
14
15
import           Text.Blaze.Html             ( Html )
import           Text.Blaze.Html5            ( (!) )
import qualified Text.Blaze.Html5            as H
import qualified Text.Blaze.Html5.Attributes as A

import qualified Site.Html.Base              as Base
16
import           Site.Types
Erik Aker's avatar
Erik Aker committed
17

18

19
contentListPage ::  PageNum -> ResourceType -> AllSiteTags -> [Resource] -> Html
20
contentListPage pgNum rtype allTags content =
21
  Base.pageSkeleton $ contentListPageBuilder pgNum rtype allTags content
22

23
24
25
26
contentListPageBuilder :: PageNum -> ResourceType -> AllSiteTags -> [Resource] -> Html
contentListPageBuilder pgNum rtype allTags content = do
  makeSectionHead rtype
  H.div ! A.class_ "row" $ do
27
28
    H.div ! A.class_ "eight columns content-list" $ do
      renderContentList content
Erik Aker's avatar
Erik Aker committed
29
      renderPaginator pgNum makePaginatorButton
30
    renderSearchSection content allTags
31
32


33
makeSectionHead :: ResourceType -> Html
34
makeSectionHead rtype =
35
36
  H.h2 ! A.class_ "section-head" $
    case rtype of
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
      About -> H.a ! A.href "/about" $ "About"
      BlogPost -> H.a ! A.href "/posts" $ "📖 Blog"
      Project -> H.a ! A.href "/projects" $ "📡 Projects"


-- | Functions for rendering content
renderContentList :: [Resource] -> Html
renderContentList content = mconcat $ map renderContentListItem content

renderContentListItem :: Resource -> Html
renderContentListItem item =
  H.div ! A.class_ "content-list-item" $ do
    renderContentListItemFeaturedImg item
    renderContentListItemLede item
    renderContentListItemTagList (item ^. tags)
52

53
54

renderContentListItemFeaturedImg :: Resource -> Html
55
renderContentListItemFeaturedImg item =
56
57
58
59
60
61
  case (item ^. featuredImage) of
    Nothing -> pure ()
    Just img -> H.div ! A.class_ "content-list-item-featured-img" $
      H.img ! A.src (H.toValue img)

renderContentListItemLede :: Resource -> Html
62
renderContentListItemLede item =
63
64
65
66
67
  H.div ! A.class_ "content-list-item-lede" $ do
    H.span ! A.class_ "content-list-item-date" $ H.toMarkup (item ^. pubdate)
    H.h3 $ H.toMarkup (item ^. title)
    H.p $ H.toMarkup (item ^. lede)
    H.div ! A.class_ "content-list-item-read-more" $
68
      readMoreLink item
69
70


71
readMoreLink :: Resource -> Html
72
readMoreLink item =
73
  if (item ^. resourceType) == BlogPost
74
75
    then H.a ! A.href (H.toValue $ "/posts/" <> getPidAsText item) $ "Read More..."
    else H.a ! A.href (H.toValue $ "/projects/" <> getPidAsText item) $ "Read More..."
76

77
78
79
80
81
82
83
84
85
86
87
renderContentListItemTagList :: [Text] -> Html
renderContentListItemTagList tags =
  H.div ! A.class_ "content-list-item-tags" $ do
    H.span $ H.i ! A.class_ "fa fa-tag" $ ""
    H.ul $ mconcat (map renderContentListItemTag tags)

renderContentListItemTag :: Text -> Html
renderContentListItemTag tag = H.li ! A.class_ "content-list-item-tag" $ H.toMarkup tag


-- | Auxiliary page content: paginator, search column, etc.
88
89
-- TODO: Make it so page numbers are *links* to other pages.
-- Create Link-function argument: PageNum -> (Int -> Html) -> Html
Erik Aker's avatar
Erik Aker committed
90
renderPaginator :: PageNum -> (Int -> Html) -> Html
91
renderPaginator (totalPages, currentPageNum) pagintorLinker =
92
93
  H.div ! A.class_ "content-list-paginator" $ do
    makeMaybeValidLeftArrow currentPageNum
Erik Aker's avatar
Erik Aker committed
94
    mconcat $ map pagintorLinker [1..currentPageNum - 1]
95
    H.div ! A.class_ "paginator active" $ H.toMarkup currentPageNum
Erik Aker's avatar
Erik Aker committed
96
    mconcat $ map pagintorLinker [currentPageNum + 1..totalPages]
97
98
99
    makeMaybeValidRightArrow totalPages currentPageNum

makePaginatorButton :: Int -> Html
100
101
makePaginatorButton num = H.div ! A.class_ "paginator" $
  H.a ! A.href (H.toValue $ "/posts/" <> show num) $ H.toMarkup num
102
103
104


makeMaybeValidLeftArrow :: Int -> Html
105
makeMaybeValidLeftArrow currentPageNum =
106
107
108
109
110
  if currentPageNum == 1
    then H.div ! A.class_ "paginator invalid" $ "<"
    else H.div ! A.class_ "paginator valid" $ "<"

makeMaybeValidRightArrow :: PageTotal -> CurrentPage -> Html
111
makeMaybeValidRightArrow totalPages currentPageNum =
112
113
114
115
116
117
118
119
  if currentPageNum == totalPages
    then H.div ! A.class_ "paginator invalid" $ ">"
    else H.div ! A.class_ "paginator valid" $ ">"


renderSearchSection :: [Resource] -> AllSiteTags -> Html
renderSearchSection content allTags =
  H.div ! A.class_ "four columns" $ do
120
121
    H.form ! A.method "post" ! A.action "/search" $
      H.input ! A.class_ "u-full-width" ! A.placeholder "search ekadanta.co" ! A.name "query" ! A.type_ "text"
122
    H.h3 "Tags"
Erik Aker's avatar
Erik Aker committed
123
    H.ul ! A.class_ "content-search-tags" $ renderSearchTags (foldMap _tags content) allTags
124
125
126

renderSearchTags :: [Text] -> AllSiteTags -> Html
renderSearchTags currentTags allTags = do
127
128
  let hashTags = HS.fromList allTags
      activeHashTags = HS.fromList currentTags
129
130
131
132
      inactiveTags = HS.difference hashTags activeHashTags
      makeActiveTag tg = H.li ! A.class_ "active" $ H.toMarkup tg
      makeInactiveTag = H.li . H.toMarkup

Erik Aker's avatar
Erik Aker committed
133
134
  foldMap makeActiveTag (HS.toList activeHashTags)
  foldMap makeInactiveTag (HS.toList inactiveTags)
135