From 8a750bd133d3f7d57ce87ac66e691f4d1ea6714f Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Wed, 25 Apr 2012 20:22:45 +0200 Subject: * almost done moving to Hamlet from Blaze --- src/Blog.hs | 501 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 263 insertions(+), 238 deletions(-) (limited to 'src') diff --git a/src/Blog.hs b/src/Blog.hs index d7a53e1f4225..538dd9212441 100644 --- a/src/Blog.hs +++ b/src/Blog.hs @@ -1,25 +1,20 @@ -{-# LANGUAGE OverloadedStrings, ScopedTypeVariables, DeriveDataTypeable, RecordWildCards #-} +{-# LANGUAGE OverloadedStrings, ScopedTypeVariables, DeriveDataTypeable, QuasiQuotes, RecordWildCards #-} module Blog where -import Control.Monad (when, unless) -import Data.Data (Data, Typeable) -import Data.List (intersperse) -import Data.Monoid (mempty) -import Data.Text (Text) -import qualified Data.Text as T -import Data.Time -import Network.Captcha.ReCaptcha -import System.Locale (defaultTimeLocale) -import Text.Blaze (toValue, preEscapedText, preEscapedString) -import Text.Blaze.Html5 (Html, (!), a, form, input, p, toHtml, label) -import Text.Blaze.Html5.Attributes (action, enctype, href, name, size, type_, value) -import qualified Text.Blaze.Html5 as H -import qualified Text.Blaze.Html5.Attributes as A -import Text.XHtml.Strict (showHtmlFragment) +import Control.Monad (when, unless) +import Data.Data (Data, Typeable) +import Data.List (intersperse) +import Data.Monoid (mempty) +import Data.Text (Text, append, pack, empty) +import Data.Time +import Network.Captcha.ReCaptcha +import System.Locale (defaultTimeLocale) +import Text.Hamlet +import Locales +import BlogDB -import Locales -import BlogDB +import qualified Data.Text as T -- custom list functions intersperse' :: a -> [a] -> [a] @@ -28,21 +23,12 @@ intersperse' sep l = sep : intersperse sep l replace :: Eq a => a -> a -> [a] -> [a] replace x y = map (\z -> if z == x then y else z) --- javascript and others - -captcha :: Html -captcha = H.div ! A.class_ "cCaptcha" $ - do H.script ! A.src "http://api.recaptcha.net/challenge?k=6LfQXccSAAAAAIjKm26XlFnBMAgvaKlOAjVWEEnM" ! A.type_ "text/javascript" $ "" - H.noscript $ H.iframe ! A.src "http://api.recaptcha.net/noscript?k=6LfQXccSAAAAAIjKm26XlFnBMAgvaKlOAjVWEEnM" ! A.height "300" ! - A.width "500" ! A.seamless "" $ do - H.br - H.textarea ! A.name "recaptcha_challenge_field" ! A.rows "3" ! A.cols "40" $ "" - H.input ! A.type_ "hidden" ! A.name "recaptcha_response_field" ! A.value "manual_challenge" +show' :: Show a => a -> Text +show' = pack . show -captchaOptions :: BlogLang -> Html -captchaOptions lang = H.script ! A.type_ "text/javascript" $ toHtml $ - T.concat ["var RecaptchaOptions = { theme: 'clean', lang: '", showLangText lang, "'};"] +data BlogURL = BlogURL +-- javascript and others analytics :: Text analytics = T.pack $ unlines [""] -- blog HTML - blogTemplate :: BlogLang -> Text -> Html -> Html -blogTemplate lang t_append body = H.docTypeHtml $ do --add body - H.head $ do - H.title $ (toHtml $ blogTitle lang t_append) - H.link ! A.rel "alternate" ! A.type_ "application/rss+xml" ! A.title "RSS-Feed" ! A.href (toValue feedURL) - H.link ! A.rel "stylesheet" ! A.type_ "text/css" ! A.href "/static/blogv33.css" ! A.media "all" - --H.link ! A.rel "stylesheet" ! A.type_ "text/css" ! A.href "/res/blogstyle.css" ! A.media "all" - H.meta ! A.httpEquiv "content-type" ! A.content "text/html;charset=UTF-8" - --H.style ! A.type_ "text/css" ! A.title "iOS iMessage" ! A.media "screen and (max-device-width: 1024px)" $ "#cosx{display:none;}" - preEscapedText analytics - H.body $ do - H.div ! A.class_ "header" $ do - H.a ! A.class_ "btitle" ! A.href (toValue $ "/" ++ show lang) $ - toHtml $ blogTitle lang "" - H.p ! A.style "clear: both;" $ do - H.span ! A.class_ "contacts" ! A.id "cosx" $ contactInfo iMessage - -- H.span ! A.id "cios" ! A.style "display:none;" $ H.b $ contactInfo "sms:tazjin@me.com" - H.span ! A.class_ "righttext" $ preEscapedText $ rightText lang - H.div ! A.class_ "middle" $ do - body - H.div ! A.class_ "footer" $ do - showFooter lang $ T.pack version - H.div ! A.class_ "centerbox" $ - H.span ! A.style "font-size: 17px; font-family: Helvetica;" $ "ಠ_ಠ" - --H.img ! A.src "http://cl.ly/F9m4/idiots.png" ! A.alt "" - where - contactInfo (imu :: Text) = do - toHtml $ contactText lang - H.a ! A.class_ "link" ! A.href (toValue mailTo) $ "Mail" - ", " - H.a ! A.class_ "link" ! A.href (toValue twitter) ! A.target "_blank" $ "Twitter" - toHtml $ orText lang - H.a ! A.class_ "link" ! A.href (toValue imu) ! A.target "_blank" $ "iMessage" - "." - feedURL = "/" ++ show lang ++ "/rss.xml" +blogTemplate lang t_append body = [shamlet| +$doctype 5 + + #{blogTitle lang t_append} + <link rel="stylesheet" type="text/css" href="/static/blogv33.css" media="all"> + <link rel="alternate" type="application/rss+xml" title="RSS-Feed" href=#{rssUrl}> + <meta http-equiv="content-type" content="text/html;charset=UTF-8"> + #{analytics} + <body> + <div class="header"> + <a class="btitle" href=#{append "/" (show' lang)}>#{blogTitle lang empty} + <p style="clear: both;"> + <span class="contacts" id="cosx">#{contactInfo iMessage} + <span class="righttext">#{rightText lang} + <div class="middle"> + #{body} + <div class="footer"> + #{showFooter lang $ pack version} + <div class="centerbox"> + <span style="font-size:17px;font-family:Helvetica;">ಠ_ಠ +|] + where + rssUrl = T.concat ["/", show' lang, "/rss.xml"] + contactInfo imu = [shamlet| +#{contactText lang} +<a class="link" href=#{mailTo}>Mail +, # +<a class="link" href=#{twitter} target="_blank">Twitter +#{orText lang} +<a class="link" href=#{imu} target="_blank">iMessage +. +|] -renderEntries :: Bool -> [Entry] -> Text -> Maybe Html -> Html -renderEntries showAll entries topText footerLinks = do - H.span ! A.class_ "innerTitle" $ toHtml topText - H.div ! A.class_ "innerContainer" $ do - H.ul ! A.style "max-width: 57em;" $ if' showAll - (mapM_ showEntry entries) - (mapM_ showEntry $ take 6 entries) - getFooterLinks footerLinks - where - showEntry :: Entry -> Html - showEntry e = H.li $ do - entryLink e $ T.pack $ show(length $ comments e) - preEscapedText $ T.append " " $ btext e - when ( mtext e /= T.empty ) $ - H.p $ entryLink e $ readMore $ lang e - unless ( mtext e /= T.empty ) $ - preEscapedText "<br> " - entryLink :: Entry -> Text -> Html - entryLink e s = H.a ! A.href (toValue $ concat $ intersperse' "/" $ linkElems e) $ - toHtml (T.concat ["[", s, "]"]) - linkElems e = [show(lang e), show $ entryId e] - getFooterLinks (Just h) = h - getFooterLinks Nothing = mempty +showFooter :: BlogLang -> Text -> Html +showFooter l v = [shamlet| +<div class="rightbox" style="text-align:right;"> + Proudly made with # + <a class="link" href="http://haskell.org">Haskell + , # + <a class="link" href="http://hackage.haskell.org/package/acid-state-0.6.3">Acid-State + / and without PHP, Java, Perl, MySQL and Python. + <p> + <a class="link" href=#{repoURL}>#{append "Version " v} +   + <a class="link" href="/notice">#{noticeText l} +|] -renderEntry :: Entry -> Html -renderEntry (Entry{..}) = do - H.span ! A.class_ "innerTitle" $ toHtml $ title - H.span ! A.class_ "righttext" $ H.i $ toHtml $ woText - H.div ! A.class_ "innerContainer" $ do - H.article $ H.ul ! A.style "max-width: 57em;" $ H.li $ do - preEscapedText $ btext - H.p $ preEscapedText $ mtext - H.div ! A.class_ "innerBoxComments" $ do - H.div ! A.class_ "cHead" $ toHtml $ cHead lang -- ! A.style "font-size:large;font-weight:bold;" - H.ul ! A.style "max-width: 57em;" $ renderComments comments lang - renderCommentBox lang entryId +renderEntries :: Bool -> [Entry] -> Text -> Maybe Html -> Html +renderEntries showAll entries topText footerLinks = [shamlet| +<span class="innerTitle">#{topText} +<div class="innerContainer"> + <ul style="max-width:57em;"> + $forall entry <- elist + <li> + <a href=#{linkElems entry}>#{linkText $ length $ comments entry} + #{append " " $ btext entry} + $if ((/=) (mtext entry) empty) + <p><a href=#{linkElems entry}>#{readMore $ lang entry} + $else + <br>  + $maybe links <- footerLinks + #{links} +|] where - woText = flip T.append author $ T.pack $ (formatTime defaultTimeLocale (eTimeFormat lang) edate) + elist = if' showAll entries (take 6 entries) + linkElems Entry{..} = concat $ intersperse' "/" [show lang, show entryId] + linkText n = T.concat ["[", show' n, "]"] -renderCommentBox :: BlogLang -> EntryId -> Html -renderCommentBox cLang cId = do - H.div ! A.class_ "cHead" $ toHtml $ cwHead cLang - captchaOptions cLang - H.form ! A.method "POST" ! A.action (toValue $ "/" ++ (show cLang) ++ "/postcomment/" ++ show cId) $ do - H.p $ H.input ! A.name "cname" ! A.placeholder "Name" ! A.class_ "cInput" - H.p $ H.label $ H.textarea ! A.name "ctext" ! A.cols "50" ! A.rows "13" ! A.class_ "cInput" ! - A.placeholder (toValue $ cTextPlaceholder cLang) $ mempty - -- H.p $ H.label $ captcha - H.p $ H.input ! A.class_ "cInput" ! A.style "width: 120px;" ! A.type_ "submit" ! A.value (toValue $ cSend cLang) +showLinks :: Maybe Int -> BlogLang -> Html +showLinks (Just i) lang = [shamlet| + $if ((>) i 1) + <div class="centerbox"> + <a href=#{nLink $ succ i}>#{backText lang} + / -- # + <a href=#{nLink $ pred i}>#{nextText lang} + $elseif ((<=) i 1) + #{showLinks Nothing lang} +|] + where + nLink page = T.concat ["/", show' lang, "/?page=", show' page] +showLinks Nothing lang = [shamlet| +<div class="centerbox"> + <a href=#{nLink}>#{backText lang} +|] + where + nLink = T.concat ["/", show' lang, "/?page=2"] -renderComments :: [Comment] -> BlogLang -> Html -renderComments [] lang = H.li $ toHtml $ noComments lang -renderComments comments lang = mapM_ showComment comments - where - showComment :: Comment -> Html - showComment (Comment{..}) = H.li $ do - H.i $ toHtml $ T.append cauthor ": " - preEscapedText ctext - H.p ! A.class_ "tt" $ toHtml $ timeString cdate - timeString t = formatTime defaultTimeLocale (cTimeFormat lang) t +renderEntry :: Entry -> Html +renderEntry Entry{..} = [shamlet| +<span class="innerTitle">#{title} +<span class="righttext"><i>#{woText} +<div class="innerContainer"> + <article> + <ul style="max-width:57em;"> + <li> + #{btext} + <p>#{mtext} + <div class="innerBoxComments"> + <div class="cHead">#{cHead lang} + <ul style="max-width:57em;">#{renderComments comments lang} + #{renderCommentBox lang entryId} +|] + where + woText = flip T.append author $ T.pack $ (formatTime defaultTimeLocale (eTimeFormat lang) edate) -showLinks :: Maybe Int -> BlogLang -> Html -showLinks (Just i) lang - | ( i > 1) = H.div ! A.class_ "centerbox" $ do - H.a ! A.href (toValue $ "/" ++ show lang ++ "/?page=" ++ show (i+1)) $ - toHtml $ backText lang - toHtml (" -- " :: Text) - H.a ! A.href (toValue $ "/" ++ show lang ++ "/?page=" ++ show (i-1)) $ - toHtml $ nextText lang - | ( i <= 1 ) = showLinks Nothing lang -showLinks Nothing lang = H.div ! A.class_ "centerbox" $ - H.a ! A.href (toValue $ "/" ++ show lang ++ "/?page=2") $ - toHtml $ backText lang +renderComments :: [Comment] -> BlogLang -> Html +renderComments [] lang = [shamlet|<li>#{noComments lang}|] +renderComments comments lang = [shamlet| +$forall comment <- comments + <li> + <i>#{append (cauthor comment) ": "} + #{ctext comment} + <p class="tt">#{timeString $ cdate comment} +|] + where + timeString = formatTime defaultTimeLocale (cTimeFormat lang) -showFooter :: BlogLang -> Text -> Html -showFooter l v = H.div ! A.class_ "rightbox" ! A.style "text-align:right;" $ do - toHtml ("Proudly made with " :: Text) - H.a ! A.class_ "link" ! A.href "http://haskell.org" $ "Haskell" - toHtml (", " :: Text) - H.a ! A.class_ "link" ! A.href "http://hackage.haskell.org/package/acid-state-0.6.3" $ "Acid-State" - toHtml (" and without PHP, Java, Perl, MySQL and Python." :: Text) - H.br - H.a ! A.class_ "link" ! A.href (toValue repoURL) $ toHtml $ T.append "Version " v - preEscapedText " " - H.a ! A.class_ "link" ! A.href "/notice" $ toHtml $ noticeText l + +renderCommentBox :: BlogLang -> EntryId -> Html +renderCommentBox cLang cId = [shamlet| +<div class="cHead">#{cwHead cLang} +<form method="POST" action=#{aLink}> + <p><input name="cname" placeholder="Name" class="cInput"> + <p> + <label> + <textarea name="ctext" cols="50" rows="13" class="cInput" placeholder=#{cTextPlaceholder cLang}> + <p><input class="cInput" style="width:120px;" type="submit" value=#{cSend cLang}> +|] + where + aLink = T.concat ["/", show' cLang, "/postcomment", show' cId] showSiteNotice :: Html -showSiteNotice = H.docTypeHtml $ do - H.title $ "Impressum" - H.h2 $ preEscapedText "Impressum und <a alt=\"Verantwortlich im Sinne des Presserechtes\">ViSdP</a>" - H.i $ "[German law demands this]" - H.br - H.p $ do - toHtml ("Vincent Ambo" :: Text) - H.br - toHtml ("Benfleetstr. 8" :: Text) - H.br - toHtml ("50858 Köln" :: Text) - H.p $ H.a ! A.href "/" ! A.style "color:black" $ "Back" +showSiteNotice = [shamlet| +$doctype 5 +<head> + <title>Impressum +<body> + <h2> + Impressum und # + <a alt="Verantwortlich im Sinne des Presserechtes">ViSdP + <i>[German law demands this] + <br> + <p> + Vincent Ambo + <br> + Benfleetstr. 8 + <br> + 50858 Köln + <p><a href="/" style="color:black;">Back +|] {- Administration pages -} adminTemplate :: Text -> Html -> Html -adminTemplate title body = H.docTypeHtml $ do - H.head $ do - H.link ! A.rel "stylesheet" ! A.type_ "text/css" ! A.href "/static/admin.css" ! A.media "all" - H.meta ! A.httpEquiv "content-type" ! A.content "text/html;charset=UTF-8" - H.title $ toHtml $ T.append "TazBlog Admin: " title - H.body - body +adminTemplate title body = [shamlet| +$doctype 5 +<head> + <link rel="stylesheet" type="text/css" href="/static/admin.css" media="all"> + <meta http-equiv="content-type" content="text/html;charset=UTF-8"> + <title>#{append "TazBlog Admin: " title} +<body> + #{body} +|] adminLogin :: Html -adminLogin = adminTemplate "Login" $ - H.div ! A.class_ "loginBox" $ do - H.div ! A.class_ "loginBoxTop" $ "TazBlog Admin: Login" - H.div ! A.class_ "loginBoxMiddle" $ H.form ! A.action "/dologin" ! A.method "post" $ do - H.p $ "Account ID" - H.p $ H.input ! A.type_ "text" ! A.style "font-size: 2;" - ! A.name "account" -- ! A.value "tazjin" ! A.readonly "1" - H.p $ "Passwort" - H.p $ H.input ! A.type_ "password" ! A.style "font-size: 2;" ! A.name "password" - H.p $ H.input ! A.alt "Anmelden" ! A.type_ "image" ! A.src "/static/signin.gif" +adminLogin = adminTemplate "Login" $ [shamlet| +<div class="loginBox"> + <div class="loginBoxTop">TazBlog Admin: Login + <div class="loginBoxMiddle"> + <form action="/dologin" method="POST"> + <p>Account ID + <p><input type="text" style="font-size:2;" name="account" value="tazjin" readonly="1"> + <p>Passwort + <p><input type="password" style="font-size:2;" name="password"> + <p><input alt="Anmelden" type="image" src="/static/signin.gif"> +|] adminIndex :: Text -> Html -adminIndex sUser = adminTemplate "Index" $ - H.div ! A.style "float: center;" $ - H.form ! A.action "/admin/postentry" ! A.method "POST" $ do - H.table $ do - H.tr $ do H.td $ "Titel:" - H.td $ H.input ! A.type_ "text" ! A.name "title" - H.tr $ do H.td $ "Sprache:" - H.td $ H.select ! A.name "lang" $ do - H.option ! A.value "de" $ "Deutsch" - H.option ! A.value "en" $ "Englisch" - H.tr $ do H.td ! A.style "vertical-align: top;" $ "Text:" - H.td $ H.textarea ! A.name "btext" ! A.cols "100" ! A.rows "15" $ mempty - H.tr $ do H.td ! A.style "vertical-align: top;" $ "Mehr Text:" - H.td $ H.textarea ! A.name "mtext" ! A.cols "100" ! A.rows "15" $ mempty - H.input ! A.type_ "hidden" ! A.name "author" ! A.value (toValue sUser) - H.input ! A.style "margin-left: 20px" ! A.type_ "submit" ! A.value "Absenden" - adminFooter +adminIndex sUser = adminTemplate "Index" $ [shamlet| +<div style="float:center;"> + <form action="/admin/postentry" method="POST"> + <table> + <tr> + <thead><td>Titel: + <td><input type="text" name="title"> + <tr> + <thead><td>Sprache: + <td><select name="lang"> + <option value="de">Deutsch + <option value="en">Englisch + <tr> + <thead><td>Text: + <td><textarea name="btext" cols="100" rows="15"> + <tr> + <thead><td style="vertical-align:top;">Mehr Text: + <td><textarea name="mtext" cols="100" rows="15"> + <input type="hidden" name="author" value=#{sUser}> + <input style="margin-left:20px;" type="submit" value="Absenden"> + #{adminFooter} +|] adminFooter :: Html -adminFooter = H.p $ do - preEscapedText "<a href=/>Startseite</a> -- Entrylist: <a href=/admin/entrylist/de>DE</a>" - preEscapedText " & <a href=/admin/entrylist/en>EN</a> -- <a href=#>Backup</a> (NYI)" +adminFooter = [shamlet| +<a href="/">Startseite +/ -- Entrylist: # +<a href="/admin/entrylist/de">DE +/ & # +<a href="/admin/entrylist/en">EN +/ -- # +<a href="#">Backup +/ (NYI) +|] adminEntryList :: [Entry] -> Html -adminEntryList entries = adminTemplate "Entrylist" $ - H.div ! A.style "float: center;" $ do - H.table $ do - mapM_ showEntryItem entries - adminFooter - where - showEntryItem :: Entry -> Html - showEntryItem (Entry{..}) = H.tr $ do - H.td $ H.a ! A.href (toValue $ "/admin/edit/" ++ show entryId) $ toHtml title - H.td $ toHtml $ formatTime defaultTimeLocale "[On %D at %H:%M]" edate - +adminEntryList entries = adminTemplate "EntryList" $ [shamlet| +<div style="float: center;"> + <table> + $forall entry <- entries + <tr> + <td><a href=#{append "/admin/edit" (show' $ entryId entry)}>#{title entry} + <td>#{formatPostDate $ edate entry} +|] + where + formatPostDate = formatTime defaultTimeLocale "[On %D at %H:%M]" editPage :: Entry -> Html -editPage (Entry{..}) = adminTemplate "Index" $ - H.div ! A.style "float: center;" $ - H.form ! A.action "/admin/updateentry" ! A.method "POST" $ do - H.table $ do - H.tr $ do H.td $ "Titel:" - H.td $ H.input ! A.type_ "text" ! A.name "title" ! A.value (toValue title) - H.tr $ do H.td ! A.style "vertical-align: top;" $ "Text:" - H.td $ H.textarea ! A.name "btext" ! A.cols "100" ! A.rows "15" $ toHtml btext - H.tr $ do H.td ! A.style "vertical-align: top;" $ "Mehr Text:" - H.td $ H.textarea ! A.name "mtext" ! A.cols "100" ! A.rows "15" $ toHtml mtext - H.input ! A.type_ "hidden" ! A.name "eid" ! A.value (toValue $ unEntryId entryId) - H.input ! A.style "margin-left: 20px" ! A.type_ "submit" ! A.value "Absenden" - H.div ! A.class_ "editComments" $ editComments comments entryId - H.p $ do preEscapedText "<a href=/>Startseite</a> -- Entrylist: <a href=/admin/entrylist/de>DE</a>" - preEscapedText " & <a href=/admin/entrylist/en>EN</a> -- <a href=#>Backup</a> (NYI)" +editPage (Entry{..}) = adminTemplate "Index" $ [shamlet| +<div style="float:center;"> + <form action="/admin/updateentry" method="POST"> + <table> + <tr> + <td>Titel: + <td><input type="text" name="title" value=#{title}> + <tr> + <td style="vertical-align:top;">Text: + <td><textarea name="btext" cols="100" rows="15">#{btext} + <tr> + <td style="vertical-align:top;">Mehr Text: + <td><textarea name="mtext" cols="100" rows="15">#{mtext} + <input type="hidden" name="eid" value=#{unEntryId entryId}> + <input type="submit" style="margin-left:20px;" value="Absenden"> + <div class="editComments">#{editComments comments entryId} + <p>#{adminFooter} +|] editComments :: [Comment] -> EntryId -> Html -editComments clist eId = H.table $ mapM_ editComment clist - where - editComment (Comment{..}) = H.tr $ do H.td $ toHtml cauthor - H.td $ toHtml $ formatTime defaultTimeLocale "%c" cdate - H.td $ cDeleteLink cdate - cDeleteLink cdate = H.a ! A.href (toValue $ "/admin/cdelete/" ++ show eId - ++ formatTime defaultTimeLocale "/%s%Q" cdate) $ "Löschen" +editComments comments eId = [shamlet| +<table> + $forall c <- comments + <tr> + <td>#{cauthor c} + <td>#{cPostTime $ cdate c} + <tr> + <td><a href=#{cDeleteLink $ cdate c}>Löschen +|] + where + cPostTime = formatTime defaultTimeLocale "%c" + cDeleteLink cd = concat ["/admin/cdelete", show eId, formatTime defaultTimeLocale "/%s%Q" cd] commentDeleted :: EntryId -> Html -commentDeleted eId = adminTemplate "Kommentar gelöscht" $ do - H.div $ "Der Kommentar wurde gelöscht." - H.br - H.a ! A.href (toValue $ "/de/" ++ show eId) $ "Eintrag ansehen | " - H.a ! A.href (toValue $ "/admin/edit/" ++ show eId) $ "Eintrag bearbeiten" +commentDeleted eId = adminTemplate "Kommentar gelöscht" $ [shamlet| +<div>Der Kommentar wurde gelöscht. +<br> +<a href=#{append "/de/" $ show' eId}>Eintrag ansehen | # +<a href=#{append "/admin/edit/" $ show' eId}>Eintrag bearbeiten +|] --- Error pages showError :: BlogError -> BlogLang -> Html -showError NotFound l = blogTemplate l (T.append ": " $ notFoundTitle l) $ do - H.span ! A.class_ "innerTitle" $ toHtml $ notFoundTitle l - H.div ! A.class_ "innerContainer" $ do - H.p ! A.class_ "notFoundFace" $ toHtml (":'(" :: Text) - H.p ! A.class_ "notFoundText" $ toHtml $ notFoundText l +showError NotFound l = blogTemplate l (T.append ": " $ notFoundTitle l) $ [shamlet| +<span class="innerTitle">#{notFoundTitle l} +<div class="innerTitle"> + <p class="notFoundFace">:( + <p class="notFoundText">#{notFoundText l} +|] + -- cgit 1.4.1