about summary refs log tree commit diff
path: root/services/tazblog/src/Blog.hs
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}

module Blog where

import BlogStore
import Data.Text (Text, pack)
import qualified Data.Text as T
import Data.Text.Lazy (fromStrict)
import Data.Time
import Text.Blaze.Html (preEscapedToHtml)
import Text.Hamlet
import Text.Markdown

blogTitle :: Text = "tazjin's blog"

repoURL :: Text = "https://bitbucket.org/tazjin/tazblog-haskell"

mailTo :: Text = "mailto:mail@tazj.in"

twitter :: Text = "https://twitter.com/tazjin"

replace :: Eq a => a -> a -> [a] -> [a]
replace x y = map (\z -> if z == x then y else z)

-- |After this date all entries are Markdown
markdownCutoff :: Day
markdownCutoff = fromGregorian 2013 04 28

blogTemplate :: Text -> Html -> Html
blogTemplate t_append body =
  [shamlet|
$doctype 5
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content=#{blogTitle}#{t_append}>
    <link rel="stylesheet" type="text/css" href="/static/blog.css" media="all">
    <link rel="alternate" type="application/rss+xml" title="RSS-Feed" href="/rss.xml">
    <title>#{blogTitle}#{t_append}
  <body>
    <header>
      <h1>
        <a href="/" .unstyled-link>#{blogTitle}
      <hr>
    ^{body}
    ^{showFooter}
|]

showFooter :: Html
showFooter =
  [shamlet|
<footer>
  <p .footer>Served without any dynamic languages.
  <p .footer>
    <a href=#{repoURL} .uncoloured-link>
    |
    <a href=#{twitter} .uncoloured-link>Twitter
    |
    <a href=#{mailTo} .uncoloured-link>Mail
  <p .lod>
    ಠ_ಠ
|]

isEntryMarkdown :: Entry -> Bool
isEntryMarkdown e = edate e > markdownCutoff

renderEntryMarkdown :: Text -> Html
renderEntryMarkdown = markdown def {msXssProtect = False} . fromStrict

renderEntries :: [Entry] -> Maybe Html -> Html
renderEntries entries pageLinks =
  [shamlet|
$forall entry <- entries
  <article>
    <h2 .inline>
      <a href=#{linkElems entry} .unstyled-link>
        #{title entry}
    <aside .date>
      #{pack $ formatTime defaultTimeLocale "%Y-%m-%d" $ edate entry}
    $if (isEntryMarkdown entry)
      ^{renderEntryMarkdown $ text entry}
    $else
      ^{preEscapedToHtml $ text entry}
  <hr>
$maybe links <- pageLinks
  ^{links}
|]
  where
    linkElems Entry {..} = "/" ++ show entryId

showLinks :: Maybe Int -> Html
showLinks (Just i) =
  [shamlet|
  $if ((>) i 1)
    <div .navigation>
      <a href=#{nLink $ succ i} .uncoloured-link>Earlier
      |
      <a href=#{nLink $ pred i} .uncoloured-link>Later
  $elseif ((<=) i 1)
    ^{showLinks Nothing}
|]
  where
    nLink page = T.concat ["/?page=", show' page]
showLinks Nothing =
  [shamlet|
<div .navigation>
  <a href="/?page=2" .uncoloured-link>Earlier
|]

renderEntry :: Entry -> Html
renderEntry e@Entry {..} =
  [shamlet|
<article>
  <h2 .inline>
    #{title}
  <aside .date>
    #{pack $ formatTime defaultTimeLocale "%Y-%m-%d" edate}
  $if (isEntryMarkdown e)
    ^{renderEntryMarkdown text}
  $else
    ^{preEscapedToHtml $ text}
<hr>
|]

showError :: Text -> Text -> Html
showError title err =
  blogTemplate (": " <> title)
    [shamlet|
<p>:(
<p>#{err}
<hr>
|]