{-# LANGUAGE OverloadedStrings #-}
module Clckwrks.Page.Route where
import Clckwrks (Role(..), requiresRole_)
import Clckwrks.Monad ( ClckState(plugins), query
, update, setUnique, themeTemplate, nestURL
)
import Clckwrks.Page.Types (Page(..), PageId(..), toSlug)
import Clckwrks.Page.Acid (GetPageTitle(..), IsPublishedPage(..), PageById(..))
import Clckwrks.Page.Admin.EditFeedConfig (editFeedConfig)
import Clckwrks.Page.Admin.EditPage (editPage)
import Clckwrks.Page.Admin.NewPage (newPage)
import Clckwrks.Page.Admin.Pages (pages)
import Clckwrks.Page.Admin.PreviewPage (previewPage)
import Clckwrks.Page.Atom (handleAtomFeed)
import Clckwrks.Page.Monad (PageConfig(pageClckURL), PageM, clckT2PageT, markupToContent)
import Clckwrks.Page.Types (PageKind(PlainPage, Post))
import Clckwrks.Page.BlogPage (blog)
import Clckwrks.Page.URL (PageURL(..), PageAdminURL(..))
import Control.Applicative ((<$>))
import Control.Monad.Reader (ask)
import Control.Monad.State (get)
import Data.Text (Text)
import qualified Data.Set as Set
import Happstack.Server ( Response, Happstack, escape, notFound, toResponse
, ok, internalServerError
)
import HSP.XMLGenerator (unXMLGenT)
import Web.Routes.Happstack (seeOtherURL)
import Web.Plugins.Core (getTheme)
checkAuth :: PageURL
-> PageM PageURL
checkAuth url =
do showFn <- pageClckURL <$> ask
let requiresRole = requiresRole_ showFn
case url of
ViewPage{} -> return url
ViewPageSlug{} -> return url
Blog{} -> return url
AtomFeed{} -> return url
PageAdmin {} -> requiresRole (Set.singleton Administrator) url
routePageAdmin :: PageAdminURL -> PageM Response
routePageAdmin url =
case url of
(EditPage pid) -> editPage (PageAdmin url) pid
NewPage -> newPage PlainPage
NewPost -> newPage Post
(PreviewPage pid) -> previewPage pid
EditFeedConfig -> editFeedConfig (PageAdmin url)
Pages -> pages
routePage :: PageURL
-> PageM Response
routePage url' =
do url <- checkAuth url'
setUnique 0
case url of
(ViewPage pid) ->
do r <- query (GetPageTitle pid)
case r of
Nothing ->
notFound $ toResponse ("Invalid PageId " ++ show (unPageId pid))
(Just (title, slug)) ->
seeOtherURL (ViewPageSlug pid (toSlug title slug))
(ViewPageSlug pid _slug) ->
do published <- query (IsPublishedPage pid)
if published
then do cs <- get
~(Just page) <- query (PageById pid)
let ttl = pageTitle page
bdy <- markupToContent (pageSrc page)
clckT2PageT $ themeTemplate (plugins cs) (pageThemeStyleId page) ttl () bdy
else do notFound $ toResponse ("Invalid PageId " ++ show (unPageId pid))
(Blog) -> blog
AtomFeed ->
do handleAtomFeed
(PageAdmin adminURL) -> routePageAdmin adminURL