yu-core-0.1.1.2: src/Yu/Core/View/Internal.hs
{-
Copyright (C) 2017-2018 Johann Lee <me@qinka.pro>
This file is part of Yu.
Yu is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Yu is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Yu. If not, see <http://www.gnu.org/licenses/>.
-}
{-|
Module : Yu.Core.View.Internal
Description : The internal module for view
Copyright : (C) 2017-2018 Johann Lee <me@qinka.pro>
License : GPL3
Maintainer : me@qinka.pro
Stability : experimental
Portability : unknown
The internal party for View, including Hamletic.
-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
module Yu.Core.View.Internal
( Hamletic(..)
, yuLayout
, yuErrorHandler
-- * layouts
, layoutBootstrap
) where
import Yesod.Core
import Yesod.Core.Handler
import Yesod.Core.Json
import Yu.Core.Model
import Yu.Import.Text (Text)
import qualified Yu.Import.Text as T
import Yu.Utils.Handler
-- | Hamtletic
--
-- Limit, and test
class (MonadHandler m, Mongodic a m) => Hamletic a m | m -> a where
getTitle :: m Text -- ^ get title
getFramePrefix :: m Text -- ^ get the prefix path of frame
getVersion :: m Text -- ^ get the version of blog itself or application
getRaw :: m Bool -- ^ return raw html
-- | layout for layout
type YuLayout site = ( PageContent (Route site)
-> Html -- hd
-> Text -- title
-> Html -- nav
-> Html -- top
-> Html -- bottom
-> ((Route site -> [(Text, Text)] -> Text) -> Html)
)
-- | layout with bootstrap
layoutBootstrap :: Yesod site => YuLayout site
layoutBootstrap pageContent hd title nav top bottom = [hamlet|
$newline never
$doctype 5
<html>
<head>
<title> #{pageTitle pageContent} - #{title}
<meta charset=utf-8>
<script src=prelude.js>
<meta name=viewport content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
#{hd}
^{pageHead pageContent}
<body>
#{nav}
<div id="container">
#{top}
<div id="main-part">
^{pageBody pageContent}
#{bottom}
|]
{-|
The example, or say template for layout
@
layoutXx pageContent hd title nav top bottom = [hamlet|
$newline never
$doctype 5
\<html>\
\<head\>
\<title\> #{pageTitle pageContent} - #{title}
\<meta charset=utf-8\>
\<meta name=viewport content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"\>
#{hd}
^{pageHead pageContent}
\<body\>
#{nav}
#{top}
^{pageBody pageContent}
#{bottom}
|]
@
-}
-- | the default of yu with Yesod
yuLayout :: (Hamletic a (HandlerT a IO),Yesod a)
=> YuLayout a -- ^ the layout for yu
-> WidgetT a IO () -- ^ widget
-> HandlerT a IO Html -- ^ return
yuLayout layout w = do
framePrefix <- getFramePrefix
title <- getTitle
pageContent <- widgetToPageContent w
htmls <- runDbDefault $ do
topHtml <- fetchMaybeI fetchFrame [framePrefix,"top"]
bottomHtml <- fetchMaybeI fetchFrame [framePrefix,"bottom"]
navHtml <- fetchMaybeI fetchFrame [framePrefix,"nav"]
header <- fetchMaybeI fetchFrame [framePrefix,"header"]
case (topHtml,bottomHtml,navHtml,header) of
(Just top, Just bottom, Just nav, Just hd) -> return $ Right (top,bottom,nav,hd)
_ -> return $ Left "cannot launch frames"
case htmls of
Left err -> error err
Right (top,bottom,nav,hd) -> withUrlRenderer $ layout pageContent hd title nav top bottom
-- | handler the error
yuErrorHandler :: Yesod site
=> ErrorResponse -- ^ error
-> HandlerT site IO TypedContent
yuErrorHandler er = selectRep $ do
provideJson er
provideRep $
defaultLayout [whamlet|
<h1> error
<p> #{T.show er}
|]