[blog] Implement new and simpler design
This commit is contained in:
parent
cfea17dc0d
commit
9f33d98db5
5 changed files with 98 additions and 287 deletions
35
res/blog.css
Normal file
35
res/blog.css
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
body {
|
||||||
|
margin: 40px auto;
|
||||||
|
max-width: 650px;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #383838;
|
||||||
|
padding: 0 10px
|
||||||
|
}
|
||||||
|
h1, h2, h3 {
|
||||||
|
line-height: 1.2
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.lod {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.unstyled-link {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.uncoloured-link {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
.date {
|
||||||
|
text-align: right;
|
||||||
|
font-style: italic;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.inline {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
.navigation {
|
||||||
|
text-align: center;
|
||||||
|
}
|
187
res/blog.lucius
187
res/blog.lucius
|
@ -1,187 +0,0 @@
|
||||||
@charset "UTF-8";
|
|
||||||
/* CSS Document */
|
|
||||||
@import url(http://fonts.googleapis.com/css?family=Droid+Sans+Mono);
|
|
||||||
@import url(http://fonts.googleapis.com/css?family=PT+Sans);
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: 'PT Sans', sans-serif;
|
|
||||||
min-height: 850px;
|
|
||||||
background: url(/static/bg.gif);
|
|
||||||
}
|
|
||||||
|
|
||||||
html, body {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
article a, .entry a {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wrap {
|
|
||||||
min-height: 100%;
|
|
||||||
height: auto !important;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.readmore {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
color: #EEE;
|
|
||||||
background: url(/static/hbg.jpg);
|
|
||||||
z-index: 4;
|
|
||||||
padding-left: 20px;
|
|
||||||
padding-bottom: 30px;
|
|
||||||
padding-top: 30px;
|
|
||||||
position: relative;
|
|
||||||
box-shadow: 0 6px 5px 1px #343537;
|
|
||||||
margin-bottom: 25px;
|
|
||||||
padding-left: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer {
|
|
||||||
background: url(/static/hbg.jpg);
|
|
||||||
height: 90;
|
|
||||||
z-index: 4;
|
|
||||||
position: relative;
|
|
||||||
background-color: #4A525A;
|
|
||||||
margin-top: 30px;
|
|
||||||
padding-top: 20px;
|
|
||||||
box-shadow: 0 -6px 5px 1px #343537;
|
|
||||||
color: #EEE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.header a, .footer a {
|
|
||||||
color: #EEE;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.boldify {
|
|
||||||
font-size:large;
|
|
||||||
font-weight:bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pusher {
|
|
||||||
padding-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cCaptcha {
|
|
||||||
padding: 5px;
|
|
||||||
border: 1px solid #555;
|
|
||||||
border-radius: 0.5em;
|
|
||||||
width: 606px;
|
|
||||||
background: #F9F9F9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tt {
|
|
||||||
font-family: "courier new",courier,monospace;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btitle {
|
|
||||||
text-decoration:none;
|
|
||||||
//color: #EEE;
|
|
||||||
font-size:x-large;
|
|
||||||
font-weight:bold;
|
|
||||||
margin-top: 15px;
|
|
||||||
padding-bottom: 25px;
|
|
||||||
padding-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contacts {
|
|
||||||
float: left;
|
|
||||||
font-weight: bolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
.righttext {
|
|
||||||
float:right;
|
|
||||||
padding-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notFoundFace {
|
|
||||||
height: 100px;
|
|
||||||
padding-top: 50px;
|
|
||||||
font-size:100px
|
|
||||||
}
|
|
||||||
|
|
||||||
.notFoundText {
|
|
||||||
font-size:24px;
|
|
||||||
font-weight:bold
|
|
||||||
}
|
|
||||||
|
|
||||||
/* HsColour style */
|
|
||||||
|
|
||||||
.code
|
|
||||||
{
|
|
||||||
box-shadow: 3px 3px 5px 1px #888;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 0.75em;
|
|
||||||
|
|
||||||
font-size: 11pt;
|
|
||||||
width: 60em;
|
|
||||||
color: white;
|
|
||||||
line-height: 1.2em;
|
|
||||||
font-family: 'Droid Sans Mono', sans-serif;
|
|
||||||
background: black;
|
|
||||||
background-image:url('/static/cbg.jpg');
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
.code pre
|
|
||||||
{
|
|
||||||
|
|
||||||
font-family: 'Droid Sans Mono', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
kbd
|
|
||||||
{
|
|
||||||
font-family: 'Droid Sans Mono', sans-serif;
|
|
||||||
color: #333;
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wide
|
|
||||||
{
|
|
||||||
width: 90em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
code
|
|
||||||
{
|
|
||||||
line-height: 1.5em;
|
|
||||||
border: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.source-code
|
|
||||||
{
|
|
||||||
font-size: 0.75em;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.warning
|
|
||||||
{
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.hs-keyglyph { color: DarkGoldenrod; }
|
|
||||||
.hs-layout { color: white;}
|
|
||||||
.hs-keyword { color: skyblue; }
|
|
||||||
.hs-comment, .hs-comment a { color: cadetblue;}
|
|
||||||
.hs-str { color: Darkorange; }
|
|
||||||
.hs-chr { color: RosyBrown;}
|
|
||||||
.hs-conid { color: GreenYellow; }
|
|
||||||
.hs-varid { color: white; }
|
|
||||||
.hs-num { color: white; }
|
|
||||||
.hs-varop { color: DarkGoldenrod; }
|
|
||||||
.hs-conop { color: DarkGoldenrod; }
|
|
||||||
.hs-sel { color: FireBrick; }
|
|
||||||
.hs-cpp { color: yellow; }
|
|
||||||
.hs-definition { color: gold; }
|
|
152
src/Blog.hs
152
src/Blog.hs
|
@ -28,61 +28,39 @@ show' = pack . show
|
||||||
markdownCutoff :: UTCTime
|
markdownCutoff :: UTCTime
|
||||||
markdownCutoff = fromJust $ parseTimeM False defaultTimeLocale "%s" "1367149834"
|
markdownCutoff = fromJust $ parseTimeM False defaultTimeLocale "%s" "1367149834"
|
||||||
|
|
||||||
|
|
||||||
-- blog CSS (admin is still static)
|
|
||||||
stylesheetSource = $(luciusFile "res/blog.lucius")
|
|
||||||
blogStyle = renderCssUrl undefined stylesheetSource
|
|
||||||
|
|
||||||
-- blog HTML
|
-- blog HTML
|
||||||
blogTemplate :: BlogLang -> Text -> Html -> Html
|
blogTemplate :: BlogLang -> Text -> Html -> Html
|
||||||
blogTemplate lang t_append body = [shamlet|
|
blogTemplate lang t_append body = [shamlet|
|
||||||
$doctype 5
|
$doctype 5
|
||||||
<head>
|
<head>
|
||||||
<title>#{blogTitle lang t_append}
|
<meta charset="utf-8">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/bootstrap.css" media="all">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/blogv40.css" media="all">
|
<link rel="stylesheet" type="text/css" href="/static/blog.css" media="all">
|
||||||
<link rel="alternate" type="application/rss+xml" title="RSS-Feed" href=#{rssUrl}>
|
<link rel="alternate" type="application/rss+xml" title="RSS-Feed" href=#{rssUrl}>
|
||||||
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
|
<title>#{blogTitle lang t_append}
|
||||||
<body>
|
<body>
|
||||||
<div #wrap>
|
<header>
|
||||||
<div .header>
|
<h1>
|
||||||
<div .container >
|
<a href="/" .unstyled-link>#{blogTitle lang empty}
|
||||||
<div .row>
|
<hr>
|
||||||
<div .span12 .blogtitle>
|
^{body}
|
||||||
<a class="btitle" href="/">#{blogTitle lang empty}
|
^{showFooter}
|
||||||
<div .row>
|
|
||||||
<br>
|
|
||||||
<div .span6>
|
|
||||||
<span .contacts #cosx>^{contactInfo}
|
|
||||||
<div .container>
|
|
||||||
^{body}
|
|
||||||
<footer .footer>
|
|
||||||
^{showFooter $ pack version}
|
|
||||||
|]
|
|]
|
||||||
where
|
where
|
||||||
rssUrl = T.concat ["/", show' lang, "/rss.xml"]
|
rssUrl = T.concat ["/", show' lang, "/rss.xml"]
|
||||||
contactInfo = [shamlet|
|
|
||||||
#{contactText lang}
|
|
||||||
<a class="link" href=#{mailTo}>Mail
|
|
||||||
#{orText lang}
|
|
||||||
<a class="link" href=#{twitter} target="_blank">Twitter
|
|
||||||
|]
|
|
||||||
|
|
||||||
showFooter :: Text -> Html
|
showFooter :: Html
|
||||||
showFooter v = [shamlet|
|
showFooter = [shamlet|
|
||||||
<div .container>
|
<footer>
|
||||||
<div .row>
|
<p .footer>Served without any dynamic languages.
|
||||||
<div .span12 .righttext style="text-align: right;margin-right:-200px">
|
<p .footer>
|
||||||
Proudly made with #
|
<a href=#{repoURL} .uncoloured-link>Version #{version}
|
||||||
<a class="link" href="http://haskell.org">Haskell
|
|
|
||||||
, #
|
<a href=#{twitter} .uncoloured-link>Twitter
|
||||||
<a class="link" href="https://hackage.haskell.org/package/acid-state">Acid-State
|
|
|
||||||
\ and without PHP, Java, Perl, MySQL and Python.
|
<a href=#{mailTo} .uncoloured-link>Mail
|
||||||
<p>
|
<p .lod>
|
||||||
<a class="link" href=#{repoURL}>#{append "Version " v}
|
ಠ_ಠ
|
||||||
<div .row .text-center>
|
|
||||||
<div .span12>
|
|
||||||
<span style="font-size:13px;font-family:Helvetica;">ಠ_ಠ
|
|
||||||
|]
|
|]
|
||||||
|
|
||||||
isEntryMarkdown :: Entry -> Bool
|
isEntryMarkdown :: Entry -> Bool
|
||||||
|
@ -91,77 +69,63 @@ isEntryMarkdown e = edate e > markdownCutoff
|
||||||
renderEntryMarkdown :: Text -> Html
|
renderEntryMarkdown :: Text -> Html
|
||||||
renderEntryMarkdown = markdown def {msXssProtect = False} . fromStrict
|
renderEntryMarkdown = markdown def {msXssProtect = False} . fromStrict
|
||||||
|
|
||||||
renderEntries :: Bool -> [Entry] -> Text -> Maybe Html -> Html
|
renderEntries :: Bool -> [Entry] -> Maybe Html -> Html
|
||||||
renderEntries showAll entries topText footerLinks = [shamlet|
|
renderEntries showAll entries pageLinks = [shamlet|
|
||||||
<div .row>
|
$forall entry <- toDisplay
|
||||||
<div .span12>
|
<article>
|
||||||
<p>
|
<h2>
|
||||||
<span class="innerTitle">
|
<a href=#{linkElems entry} .unstyled-link>
|
||||||
<b>#{topText}
|
#{title entry}
|
||||||
$forall entry <- elist
|
<aside .date>
|
||||||
<div .row>
|
#{pack $ formatTime defaultTimeLocale "%Y-%m-%d" $ edate entry}
|
||||||
<div .span2>
|
$if (isEntryMarkdown entry)
|
||||||
<a href=#{linkElems entry}>
|
^{renderEntryMarkdown $ btext entry}
|
||||||
<b>#{title entry}
|
$else
|
||||||
<br>
|
^{preEscapedToHtml $ btext entry}
|
||||||
<i>#{pack $ formatTime defaultTimeLocale "%Y-%m-%d" $ edate entry}
|
$if ((/=) (mtext entry) empty)
|
||||||
<div .span10 .entry>
|
<a .uncoloured-link href=#{linkElems entry}>
|
||||||
$if (isEntryMarkdown entry)
|
#{readMore $ lang entry}
|
||||||
^{renderEntryMarkdown $ append " " $ btext entry}
|
<hr>
|
||||||
$else
|
$maybe links <- pageLinks
|
||||||
^{preEscapedToHtml $ append " " $ btext entry}
|
|
||||||
$if ((/=) (mtext entry) empty)
|
|
||||||
<p>
|
|
||||||
<a .readmore href=#{linkElems entry}>#{readMore $ lang entry}
|
|
||||||
$else
|
|
||||||
<br>
|
|
||||||
$maybe links <- footerLinks
|
|
||||||
^{links}
|
^{links}
|
||||||
|]
|
|]
|
||||||
where
|
where
|
||||||
elist = if' showAll entries (take 6 entries)
|
toDisplay = if' showAll entries (take 6 entries)
|
||||||
linkElems Entry{..} = concat $ intersperse' "/" [show lang, show entryId]
|
linkElems Entry{..} = concat $ intersperse' "/" [show lang, show entryId]
|
||||||
|
|
||||||
showLinks :: Maybe Int -> BlogLang -> Html
|
showLinks :: Maybe Int -> BlogLang -> Html
|
||||||
showLinks (Just i) lang = [shamlet|
|
showLinks (Just i) lang = [shamlet|
|
||||||
$if ((>) i 1)
|
$if ((>) i 1)
|
||||||
<div .row .text-center>
|
<div .navigation>
|
||||||
<div .span12>
|
<a href=#{nLink $ succ i} .uncoloured-link>#{backText lang}
|
||||||
<a href=#{nLink $ succ i}>#{backText lang}
|
|
|
||||||
\ -- #
|
<a href=#{nLink $ pred i} .uncoloured-link>#{nextText lang}
|
||||||
<a href=#{nLink $ pred i}>#{nextText lang}
|
|
||||||
$elseif ((<=) i 1)
|
$elseif ((<=) i 1)
|
||||||
^{showLinks Nothing lang}
|
^{showLinks Nothing lang}
|
||||||
|]
|
|]
|
||||||
where
|
where
|
||||||
nLink page = T.concat ["/", show' lang, "/?page=", show' page]
|
nLink page = T.concat ["/", show' lang, "/?page=", show' page]
|
||||||
showLinks Nothing lang = [shamlet|
|
showLinks Nothing lang = [shamlet|
|
||||||
<div .row .text-center>
|
<div .navigation>
|
||||||
<div .span12>
|
<a href=#{nLink} .uncoloured-link>#{backText lang}
|
||||||
<a href=#{nLink}>#{backText lang}
|
|
||||||
|]
|
|]
|
||||||
where
|
where
|
||||||
nLink = T.concat ["/", show' lang, "/?page=2"]
|
nLink = T.concat ["/", show' lang, "/?page=2"]
|
||||||
|
|
||||||
renderEntry :: Entry -> Html
|
renderEntry :: Entry -> Html
|
||||||
renderEntry e@Entry{..} = [shamlet|
|
renderEntry e@Entry{..} = [shamlet|
|
||||||
<div .row .pusher>
|
<article>
|
||||||
<div .span9>
|
<h2>
|
||||||
<span .boldify>#{title}
|
#{title}
|
||||||
<div .span3>
|
<aside .date>
|
||||||
<span .righttext><i>#{woText}</i>
|
#{pack $ formatTime defaultTimeLocale "%Y-%m-%d" edate}
|
||||||
<div .row .innerContainer>
|
$if (isEntryMarkdown e)
|
||||||
<div .span10>
|
^{renderEntryMarkdown btext}
|
||||||
<article>
|
<p>^{renderEntryMarkdown $ mtext}
|
||||||
$if (isEntryMarkdown e)
|
$else
|
||||||
^{renderEntryMarkdown btext}
|
^{preEscapedToHtml $ btext}
|
||||||
<p>^{renderEntryMarkdown $ mtext}
|
<hr>
|
||||||
$else
|
|
||||||
^{preEscapedToHtml $ btext}
|
|
||||||
<p>^{preEscapedToHtml $ mtext}
|
|
||||||
|]
|
|]
|
||||||
where
|
|
||||||
woText = flip T.append author $ T.pack $ formatTime defaultTimeLocale (eTimeFormat lang) edate
|
|
||||||
|
|
||||||
{- Administration pages -}
|
{- Administration pages -}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@ if' True x _ = x
|
||||||
if' False _ y = y
|
if' False _ y = y
|
||||||
|
|
||||||
blogTitle :: BlogLang -> Text -> Text
|
blogTitle :: BlogLang -> Text -> Text
|
||||||
blogTitle DE s = T.concat ["Tazjins Blog", s]
|
blogTitle DE s = T.concat ["Tazjins blog", s]
|
||||||
blogTitle EN s = T.concat ["Tazjin's Blog", s]
|
blogTitle EN s = T.concat ["Tazjin's blog", s]
|
||||||
|
|
||||||
showLangText :: BlogLang -> Text
|
showLangText :: BlogLang -> Text
|
||||||
showLangText EN = "en"
|
showLangText EN = "en"
|
||||||
|
@ -77,8 +77,8 @@ nextText DE = "Später"
|
||||||
nextText EN = "Later"
|
nextText EN = "Later"
|
||||||
|
|
||||||
readMore :: BlogLang -> Text
|
readMore :: BlogLang -> Text
|
||||||
readMore DE = "Weiterlesen"
|
readMore DE = "[Weiterlesen]"
|
||||||
readMore EN = "Read more"
|
readMore EN = "[Read more]"
|
||||||
|
|
||||||
eTimeFormat :: BlogLang -> String
|
eTimeFormat :: BlogLang -> String
|
||||||
eTimeFormat DE = "Geschrieben am %Y-%m-%d von "
|
eTimeFormat DE = "Geschrieben am %Y-%m-%d von "
|
||||||
|
|
|
@ -40,7 +40,6 @@ tazBlog acid resDir = do
|
||||||
adminHandler acid -- this checks auth
|
adminHandler acid -- this checks auth
|
||||||
, method GET >> (ok $ toResponse adminLogin)
|
, method GET >> (ok $ toResponse adminLogin)
|
||||||
, method POST >> processLogin acid ]
|
, method POST >> processLogin acid ]
|
||||||
, dirs "static/blogv40.css" $ serveBlogStyle
|
|
||||||
, dir "static" $ staticHandler resDir
|
, dir "static" $ staticHandler resDir
|
||||||
, blogHandler acid EN
|
, blogHandler acid EN
|
||||||
, notFound $ toResponse $ showError NotFound DE
|
, notFound $ toResponse $ showError NotFound DE
|
||||||
|
@ -96,7 +95,7 @@ showIndex acid lang = do
|
||||||
entries <- query' acid (LatestEntries lang)
|
entries <- query' acid (LatestEntries lang)
|
||||||
(page :: Maybe Int) <- optional $ lookRead "page"
|
(page :: Maybe Int) <- optional $ lookRead "page"
|
||||||
ok $ toResponse $ blogTemplate lang "" $
|
ok $ toResponse $ blogTemplate lang "" $
|
||||||
renderEntries False (eDrop page entries) (topText lang) (Just $ showLinks page lang)
|
renderEntries False (eDrop page entries) (Just $ showLinks page lang)
|
||||||
where
|
where
|
||||||
eDrop :: Maybe Int -> [a] -> [a]
|
eDrop :: Maybe Int -> [a] -> [a]
|
||||||
eDrop (Just i) = drop ((i-1) * 6)
|
eDrop (Just i) = drop ((i-1) * 6)
|
||||||
|
|
Loading…
Reference in a new issue