* almost done moving to Hamlet from Blaze

This commit is contained in:
Vincent Ambo 2012-04-25 20:22:45 +02:00
parent e28c43f018
commit 8a750bd133

View file

@ -1,25 +1,20 @@
{-# LANGUAGE OverloadedStrings, ScopedTypeVariables, DeriveDataTypeable, RecordWildCards #-} {-# LANGUAGE OverloadedStrings, ScopedTypeVariables, DeriveDataTypeable, QuasiQuotes, RecordWildCards #-}
module Blog where module Blog where
import Control.Monad (when, unless) import Control.Monad (when, unless)
import Data.Data (Data, Typeable) import Data.Data (Data, Typeable)
import Data.List (intersperse) import Data.List (intersperse)
import Data.Monoid (mempty) import Data.Monoid (mempty)
import Data.Text (Text) import Data.Text (Text, append, pack, empty)
import qualified Data.Text as T import Data.Time
import Data.Time import Network.Captcha.ReCaptcha
import Network.Captcha.ReCaptcha import System.Locale (defaultTimeLocale)
import System.Locale (defaultTimeLocale) import Text.Hamlet
import Text.Blaze (toValue, preEscapedText, preEscapedString) import Locales
import Text.Blaze.Html5 (Html, (!), a, form, input, p, toHtml, label) import BlogDB
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 Locales import qualified Data.Text as T
import BlogDB
-- custom list functions -- custom list functions
intersperse' :: a -> [a] -> [a] intersperse' :: a -> [a] -> [a]
@ -28,21 +23,12 @@ intersperse' sep l = sep : intersperse sep l
replace :: Eq a => a -> a -> [a] -> [a] replace :: Eq a => a -> a -> [a] -> [a]
replace x y = map (\z -> if z == x then y else z) replace x y = map (\z -> if z == x then y else z)
show' :: Show a => a -> Text
show' = pack . show
data BlogURL = BlogURL
-- javascript and others -- 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"
captchaOptions :: BlogLang -> Html
captchaOptions lang = H.script ! A.type_ "text/javascript" $ toHtml $
T.concat ["var RecaptchaOptions = { theme: 'clean', lang: '", showLangText lang, "'};"]
analytics :: Text analytics :: Text
analytics = T.pack $ unlines ["<script type=\"text/javascript\">" analytics = T.pack $ unlines ["<script type=\"text/javascript\">"
," var _gaq = _gaq || [];" ," var _gaq = _gaq || [];"
@ -56,240 +42,279 @@ analytics = T.pack $ unlines ["<script type=\"text/javascript\">"
,"</script>"] ,"</script>"]
-- blog HTML -- blog HTML
blogTemplate :: BlogLang -> Text -> Html -> Html blogTemplate :: BlogLang -> Text -> Html -> Html
blogTemplate lang t_append body = H.docTypeHtml $ do --add body blogTemplate lang t_append body = [shamlet|
H.head $ do $doctype 5
H.title $ (toHtml $ blogTitle lang t_append) <head>
H.link ! A.rel "alternate" ! A.type_ "application/rss+xml" ! A.title "RSS-Feed" ! A.href (toValue feedURL) <title>#{blogTitle lang t_append}
H.link ! A.rel "stylesheet" ! A.type_ "text/css" ! A.href "/static/blogv33.css" ! A.media "all" <link rel="stylesheet" type="text/css" href="/static/blogv33.css" media="all">
--H.link ! A.rel "stylesheet" ! A.type_ "text/css" ! A.href "/res/blogstyle.css" ! A.media "all" <link rel="alternate" type="application/rss+xml" title="RSS-Feed" href=#{rssUrl}>
H.meta ! A.httpEquiv "content-type" ! A.content "text/html;charset=UTF-8" <meta http-equiv="content-type" 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;}" #{analytics}
preEscapedText analytics <body>
H.body $ do <div class="header">
H.div ! A.class_ "header" $ do <a class="btitle" href=#{append "/" (show' lang)}>#{blogTitle lang empty}
H.a ! A.class_ "btitle" ! A.href (toValue $ "/" ++ show lang) $ <p style="clear: both;">
toHtml $ blogTitle lang "" <span class="contacts" id="cosx">#{contactInfo iMessage}
H.p ! A.style "clear: both;" $ do <span class="righttext">#{rightText lang}
H.span ! A.class_ "contacts" ! A.id "cosx" $ contactInfo iMessage <div class="middle">
-- H.span ! A.id "cios" ! A.style "display:none;" $ H.b $ contactInfo "sms:tazjin@me.com" #{body}
H.span ! A.class_ "righttext" $ preEscapedText $ rightText lang <div class="footer">
H.div ! A.class_ "middle" $ do #{showFooter lang $ pack version}
body <div class="centerbox">
H.div ! A.class_ "footer" $ do <span style="font-size:17px;font-family:Helvetica;">_ಠ
showFooter lang $ T.pack version |]
H.div ! A.class_ "centerbox" $ where
H.span ! A.style "font-size: 17px; font-family: Helvetica;" $ "ಠ_ಠ" rssUrl = T.concat ["/", show' lang, "/rss.xml"]
--H.img ! A.src "http://cl.ly/F9m4/idiots.png" ! A.alt "" contactInfo imu = [shamlet|
where #{contactText lang}
contactInfo (imu :: Text) = do <a class="link" href=#{mailTo}>Mail
toHtml $ contactText lang , #
H.a ! A.class_ "link" ! A.href (toValue mailTo) $ "Mail" <a class="link" href=#{twitter} target="_blank">Twitter
", " #{orText lang}
H.a ! A.class_ "link" ! A.href (toValue twitter) ! A.target "_blank" $ "Twitter" <a class="link" href=#{imu} target="_blank">iMessage
toHtml $ orText lang .
H.a ! A.class_ "link" ! A.href (toValue imu) ! A.target "_blank" $ "iMessage" |]
"."
feedURL = "/" ++ show lang ++ "/rss.xml"
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>&nbsp;"
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
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
where
woText = flip T.append author $ T.pack $ (formatTime defaultTimeLocale (eTimeFormat lang) edate)
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)
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
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
showFooter :: BlogLang -> Text -> Html showFooter :: BlogLang -> Text -> Html
showFooter l v = H.div ! A.class_ "rightbox" ! A.style "text-align:right;" $ do showFooter l v = [shamlet|
toHtml ("Proudly made with " :: Text) <div class="rightbox" style="text-align:right;">
H.a ! A.class_ "link" ! A.href "http://haskell.org" $ "Haskell" Proudly made with #
toHtml (", " :: Text) <a class="link" href="http://haskell.org">Haskell
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) <a class="link" href="http://hackage.haskell.org/package/acid-state-0.6.3">Acid-State
H.br / and without PHP, Java, Perl, MySQL and Python.
H.a ! A.class_ "link" ! A.href (toValue repoURL) $ toHtml $ T.append "Version " v <p>
preEscapedText "&nbsp;" <a class="link" href=#{repoURL}>#{append "Version " v}
H.a ! A.class_ "link" ! A.href "/notice" $ toHtml $ noticeText l &nbsp;
<a class="link" href="/notice">#{noticeText l}
|]
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>&nbsp;
$maybe links <- footerLinks
#{links}
|]
where
elist = if' showAll entries (take 6 entries)
linkElems Entry{..} = concat $ intersperse' "/" [show lang, show entryId]
linkText n = T.concat ["[", show' n, "]"]
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"]
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)
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)
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 :: Html
showSiteNotice = H.docTypeHtml $ do showSiteNotice = [shamlet|
H.title $ "Impressum" $doctype 5
H.h2 $ preEscapedText "Impressum und <a alt=\"Verantwortlich im Sinne des Presserechtes\">ViSdP</a>" <head>
H.i $ "[German law demands this]" <title>Impressum
H.br <body>
H.p $ do <h2>
toHtml ("Vincent Ambo" :: Text) Impressum und #
H.br <a alt="Verantwortlich im Sinne des Presserechtes">ViSdP
toHtml ("Benfleetstr. 8" :: Text) <i>[German law demands this]
H.br <br>
toHtml ("50858 Köln" :: Text) <p>
H.p $ H.a ! A.href "/" ! A.style "color:black" $ "Back" Vincent Ambo
<br>
Benfleetstr. 8
<br>
50858 Köln
<p><a href="/" style="color:black;">Back
|]
{- Administration pages -} {- Administration pages -}
adminTemplate :: Text -> Html -> Html adminTemplate :: Text -> Html -> Html
adminTemplate title body = H.docTypeHtml $ do adminTemplate title body = [shamlet|
H.head $ do $doctype 5
H.link ! A.rel "stylesheet" ! A.type_ "text/css" ! A.href "/static/admin.css" ! A.media "all" <head>
H.meta ! A.httpEquiv "content-type" ! A.content "text/html;charset=UTF-8" <link rel="stylesheet" type="text/css" href="/static/admin.css" media="all">
H.title $ toHtml $ T.append "TazBlog Admin: " title <meta http-equiv="content-type" content="text/html;charset=UTF-8">
H.body <title>#{append "TazBlog Admin: " title}
body <body>
#{body}
|]
adminLogin :: Html adminLogin :: Html
adminLogin = adminTemplate "Login" $ adminLogin = adminTemplate "Login" $ [shamlet|
H.div ! A.class_ "loginBox" $ do <div class="loginBox">
H.div ! A.class_ "loginBoxTop" $ "TazBlog Admin: Login" <div class="loginBoxTop">TazBlog Admin: Login
H.div ! A.class_ "loginBoxMiddle" $ H.form ! A.action "/dologin" ! A.method "post" $ do <div class="loginBoxMiddle">
H.p $ "Account ID" <form action="/dologin" method="POST">
H.p $ H.input ! A.type_ "text" ! A.style "font-size: 2;" <p>Account ID
! A.name "account" -- ! A.value "tazjin" ! A.readonly "1" <p><input type="text" style="font-size:2;" name="account" value="tazjin" readonly="1">
H.p $ "Passwort" <p>Passwort
H.p $ H.input ! A.type_ "password" ! A.style "font-size: 2;" ! A.name "password" <p><input type="password" style="font-size:2;" name="password">
H.p $ H.input ! A.alt "Anmelden" ! A.type_ "image" ! A.src "/static/signin.gif" <p><input alt="Anmelden" type="image" src="/static/signin.gif">
|]
adminIndex :: Text -> Html adminIndex :: Text -> Html
adminIndex sUser = adminTemplate "Index" $ adminIndex sUser = adminTemplate "Index" $ [shamlet|
H.div ! A.style "float: center;" $ <div style="float:center;">
H.form ! A.action "/admin/postentry" ! A.method "POST" $ do <form action="/admin/postentry" method="POST">
H.table $ do <table>
H.tr $ do H.td $ "Titel:" <tr>
H.td $ H.input ! A.type_ "text" ! A.name "title" <thead><td>Titel:
H.tr $ do H.td $ "Sprache:" <td><input type="text" name="title">
H.td $ H.select ! A.name "lang" $ do <tr>
H.option ! A.value "de" $ "Deutsch" <thead><td>Sprache:
H.option ! A.value "en" $ "Englisch" <td><select name="lang">
H.tr $ do H.td ! A.style "vertical-align: top;" $ "Text:" <option value="de">Deutsch
H.td $ H.textarea ! A.name "btext" ! A.cols "100" ! A.rows "15" $ mempty <option value="en">Englisch
H.tr $ do H.td ! A.style "vertical-align: top;" $ "Mehr Text:" <tr>
H.td $ H.textarea ! A.name "mtext" ! A.cols "100" ! A.rows "15" $ mempty <thead><td>Text:
H.input ! A.type_ "hidden" ! A.name "author" ! A.value (toValue sUser) <td><textarea name="btext" cols="100" rows="15">
H.input ! A.style "margin-left: 20px" ! A.type_ "submit" ! A.value "Absenden" <tr>
adminFooter <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 :: Html
adminFooter = H.p $ do adminFooter = [shamlet|
preEscapedText "<a href=/>Startseite</a> -- Entrylist: <a href=/admin/entrylist/de>DE</a>" <a href="/">Startseite
preEscapedText " & <a href=/admin/entrylist/en>EN</a> -- <a href=#>Backup</a> (NYI)" / -- Entrylist: #
<a href="/admin/entrylist/de">DE
/ & #
<a href="/admin/entrylist/en">EN
/ -- #
<a href="#">Backup
/ (NYI)
|]
adminEntryList :: [Entry] -> Html adminEntryList :: [Entry] -> Html
adminEntryList entries = adminTemplate "Entrylist" $ adminEntryList entries = adminTemplate "EntryList" $ [shamlet|
H.div ! A.style "float: center;" $ do <div style="float: center;">
H.table $ do <table>
mapM_ showEntryItem entries $forall entry <- entries
adminFooter <tr>
where <td><a href=#{append "/admin/edit" (show' $ entryId entry)}>#{title entry}
showEntryItem :: Entry -> Html <td>#{formatPostDate $ edate entry}
showEntryItem (Entry{..}) = H.tr $ do |]
H.td $ H.a ! A.href (toValue $ "/admin/edit/" ++ show entryId) $ toHtml title where
H.td $ toHtml $ formatTime defaultTimeLocale "[On %D at %H:%M]" edate formatPostDate = formatTime defaultTimeLocale "[On %D at %H:%M]"
editPage :: Entry -> Html editPage :: Entry -> Html
editPage (Entry{..}) = adminTemplate "Index" $ editPage (Entry{..}) = adminTemplate "Index" $ [shamlet|
H.div ! A.style "float: center;" $ <div style="float:center;">
H.form ! A.action "/admin/updateentry" ! A.method "POST" $ do <form action="/admin/updateentry" method="POST">
H.table $ do <table>
H.tr $ do H.td $ "Titel:" <tr>
H.td $ H.input ! A.type_ "text" ! A.name "title" ! A.value (toValue title) <td>Titel:
H.tr $ do H.td ! A.style "vertical-align: top;" $ "Text:" <td><input type="text" name="title" value=#{title}>
H.td $ H.textarea ! A.name "btext" ! A.cols "100" ! A.rows "15" $ toHtml btext <tr>
H.tr $ do H.td ! A.style "vertical-align: top;" $ "Mehr Text:" <td style="vertical-align:top;">Text:
H.td $ H.textarea ! A.name "mtext" ! A.cols "100" ! A.rows "15" $ toHtml mtext <td><textarea name="btext" cols="100" rows="15">#{btext}
H.input ! A.type_ "hidden" ! A.name "eid" ! A.value (toValue $ unEntryId entryId) <tr>
H.input ! A.style "margin-left: 20px" ! A.type_ "submit" ! A.value "Absenden" <td style="vertical-align:top;">Mehr Text:
H.div ! A.class_ "editComments" $ editComments comments entryId <td><textarea name="mtext" cols="100" rows="15">#{mtext}
H.p $ do preEscapedText "<a href=/>Startseite</a> -- Entrylist: <a href=/admin/entrylist/de>DE</a>" <input type="hidden" name="eid" value=#{unEntryId entryId}>
preEscapedText " & <a href=/admin/entrylist/en>EN</a> -- <a href=#>Backup</a> (NYI)" <input type="submit" style="margin-left:20px;" value="Absenden">
<div class="editComments">#{editComments comments entryId}
<p>#{adminFooter}
|]
editComments :: [Comment] -> EntryId -> Html editComments :: [Comment] -> EntryId -> Html
editComments clist eId = H.table $ mapM_ editComment clist editComments comments eId = [shamlet|
where <table>
editComment (Comment{..}) = H.tr $ do H.td $ toHtml cauthor $forall c <- comments
H.td $ toHtml $ formatTime defaultTimeLocale "%c" cdate <tr>
H.td $ cDeleteLink cdate <td>#{cauthor c}
cDeleteLink cdate = H.a ! A.href (toValue $ "/admin/cdelete/" ++ show eId <td>#{cPostTime $ cdate c}
++ formatTime defaultTimeLocale "/%s%Q" cdate) $ "Löschen" <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 :: EntryId -> Html
commentDeleted eId = adminTemplate "Kommentar gelöscht" $ do commentDeleted eId = adminTemplate "Kommentar gelöscht" $ [shamlet|
H.div $ "Der Kommentar wurde gelöscht." <div>Der Kommentar wurde gelöscht.
H.br <br>
H.a ! A.href (toValue $ "/de/" ++ show eId) $ "Eintrag ansehen | " <a href=#{append "/de/" $ show' eId}>Eintrag ansehen | #
H.a ! A.href (toValue $ "/admin/edit/" ++ show eId) $ "Eintrag bearbeiten" <a href=#{append "/admin/edit/" $ show' eId}>Eintrag bearbeiten
|]
-- Error pages
showError :: BlogError -> BlogLang -> Html showError :: BlogError -> BlogLang -> Html
showError NotFound l = blogTemplate l (T.append ": " $ notFoundTitle l) $ do showError NotFound l = blogTemplate l (T.append ": " $ notFoundTitle l) $ [shamlet|
H.span ! A.class_ "innerTitle" $ toHtml $ notFoundTitle l <span class="innerTitle">#{notFoundTitle l}
H.div ! A.class_ "innerContainer" $ do <div class="innerTitle">
H.p ! A.class_ "notFoundFace" $ toHtml (":'(" :: Text) <p class="notFoundFace">:(
H.p ! A.class_ "notFoundText" $ toHtml $ notFoundText l <p class="notFoundText">#{notFoundText l}
|]