pencil-1.0.0: examples/Complex/src/Main.hs
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Pencil
import qualified Data.HashMap.Strict as H
import qualified Data.Text as T
websiteTitle :: T.Text
websiteTitle = "Complex Test"
config :: Config
config =
(updateEnv (insertText "title" websiteTitle) .
updateEnv (insertText "secret" "My global secret") .
setSourceDir "examples/Complex/site/" .
setOutputDir "examples/Complex/out/"
) defaultConfig
website :: PencilApp ()
website = do
loadAndRender "assets/style.scss"
loadAndRender "assets/giraffe.jpg"
-- Should not convert this file. Rendered as assets/examples/example.markdown.
move "assets/examples/" <$> passthrough "assets/example.markdown" >>= render
-- Static files are passed-through. Convertible files are converted.
loadResources True False "assets/fun/" >>= render
-- Copy the assets/passthroughs folder to its destination without converting
-- any of the files in there.
move "assets/passthroughs-to/" <$> passthrough "assets/passthroughs/" >>= render
-- Convertible files are converted, and static assets are passed through.
loadAndRender "assets/conversions/"
layout <- load "layout.html"
-- Load all our blog posts into `posts`, which is of type [Page]
postLayout <- load "post-layout.html"
posts <- loadPosts "blog/"
-- Build tag index pages. This is a map of a Tag (which is just text)
-- to a Page which has the environment stuffed with blog posts that has that
-- tag.
tagPages <- buildTagPages "tag-list.html" posts
-- Render all our blog posts. So for each post in posts, we:
--
-- - injectTitle - This generates a `title` variable in our env that has the
-- format of "post title - My Blog"
--
-- - injectTags - This injects some environment variables so that our blog
-- post page knows what tags it has (via `tags` variable), AND a reference to
-- the tag index page that we built above (via `this.url`). Look through
-- post-layout.html to see how to use these tag variables.
--
-- - (layout <|| postLayout <|) - We push the generated post Page into this
-- Structure, so that all blog posts share the same postLayout.
--
-- - render - Finally we render all of our blog posts into files.
--
render $ fmap ((layout <|| postLayout <|) . injectTags tagPages . injectTitle websiteTitle)
posts
-- Build our index page.
index <- load "index.html"
render $ layout <|| index <<| coll "posts" posts
-- Render tag list pages. This is so that we can go to /blog/tags/awesome to
-- see all the blog posts tagged with "awesome".
render $ fmap (layout <||) (H.elems tagPages)
-- Load RSS layout.
rssLayout <- move "blog/" <$> load "rss.xml"
-- Build RSS feed of the last 10 posts.
let rssFeedStruct = struct rssLayout <<| coll "posts" (fmap escapeXml (take 10 posts))
-- Render the RSS feed. We need to render inside a modified environment, where
-- @toTextRss@ is used as the render function, so that dates are rendered in
-- the RFC 822 format, per the RSS specification.
local (setDisplayValue toTextRss)
(render rssFeedStruct)
deep1 <- load "deep/deep1.md"
deep2 <- load "deep/deep2.html"
deep3 <- load "deep/deep3.markdown"
deep4a <- load "deep/deep4a.markdown"
deep4b <- load "deep/deep4b.md"
render $ layout <|| deep1 <| deep2 <| move "deep/index.html" deep3 <<| coll "deep4s" [deep4a, deep4b]
toPage <- to "to/" <$> load "deep/deep1.md"
render $ struct toPage
main :: IO ()
main = run website config