web-rep-0.11.0.0: src/Web/Rep/Render.hs
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE OverloadedStrings #-}
-- | Page rendering
module Web.Rep.Render
( renderPage,
renderPageWith,
renderPageHtmlWith,
renderPageAsByteString,
renderPageToFile,
renderPageHtmlToFile,
)
where
import Control.Applicative
import Control.Monad
import Data.ByteString (ByteString)
import Data.ByteString qualified as B
import Data.Foldable
import MarkupParse
import Optics.Core hiding (element)
import Web.Rep.Html
import Web.Rep.Page
-- | Render a Page with the default configuration into Html.
renderPage :: Page -> Markup
renderPage p =
(\(_, _, x) -> x) $ renderPageWith (defaultPageConfig "default") p
-- | Render a Page into Html.
renderPageHtmlWith :: PageConfig -> Page -> Markup
renderPageHtmlWith pc p =
(\(_, _, x) -> x) $ renderPageWith pc p
-- | Render a Page into css text, js text and html.
renderPageWith :: PageConfig -> Page -> (ByteString, ByteString, Markup)
renderPageWith pc p =
case pc ^. #concerns of
Inline -> (mempty, mempty, h)
Separated -> (css, js, h)
where
h =
case pc ^. #structure of
HeaderBody ->
doctypeHtml
<> element
"html"
[Attr "lang" "en"]
( element
"head"
[]
(element_ "meta" [Attr "charset" "utf-8"])
<> cssInline
<> libsCss'
<> view #htmlHeader p
)
<> element
"body"
[]
( view #htmlBody p
<> libsJs'
<> jsInline
)
Headless ->
doctypeHtml
<> element_ "meta" [Attr "charset" "utf-8"]
<> libsCss'
<> cssInline
<> view #htmlHeader p
<> p ^. #htmlBody
<> libsJs'
<> jsInline
Snippet ->
libsCss'
<> cssInline
<> view #htmlHeader p
<> view #htmlBody p
<> libsJs'
<> jsInline
css :: ByteString
css = renderCss (view #renderStyle pc) (p ^. #cssBody)
js :: ByteString
js = jsByteString (p ^. #jsGlobal <> onLoad (p ^. #jsOnLoad))
cssInline
| pc ^. #concerns == Separated || css == mempty = mempty
| otherwise = elementc "style" [Attr "type" "text/css"] css
jsInline
| pc ^. #concerns == Separated || js == mempty = mempty
| otherwise = elementc "script" [] js
libsCss' =
case pc ^. #concerns of
Inline -> view #libsCss p
Separated ->
view #libsCss p
<> libCss (strToUtf8 $ pc ^. #filenames % #cssConcern)
libsJs' =
case pc ^. #concerns of
Inline -> p ^. #libsJs
Separated ->
view #libsJs p
<> libJs (strToUtf8 $ pc ^. #filenames % #jsConcern)
-- | Render Page concerns to files.
renderPageToFile :: FilePath -> PageConfig -> Page -> IO ()
renderPageToFile dir pc page =
sequenceA_ $ liftA2 writeFile' (pc ^. #filenames) (renderPageAsByteString pc page)
where
writeFile' fp s = unless (s == mempty) (B.writeFile (dir <> "/" <> fp) s)
-- | Render a page to just a Html file.
renderPageHtmlToFile :: FilePath -> PageConfig -> Page -> IO ()
renderPageHtmlToFile file pc page =
B.writeFile file (markdown_ (view #renderStyle pc) Html $ renderPageHtmlWith pc page)
-- | Render a Page as Text.
renderPageAsByteString :: PageConfig -> Page -> Concerns ByteString
renderPageAsByteString pc p =
case pc ^. #concerns of
Inline -> Concerns mempty mempty (markdown_ (view #renderStyle pc) Html h)
Separated -> Concerns css js (markdown_ (view #renderStyle pc) Html h)
where
(css, js, h) = renderPageWith pc p