Stop hardcoding feed URL; update environment variable helper function names and add new SAMPU_BASEURL env var
This commit is contained in:
parent
83ea5b77e9
commit
1ef77413db
@ -1,2 +1,3 @@
|
|||||||
APPLICATIONPORT="3000"
|
SAMPU_PORT="3000"
|
||||||
BLOGTITLE="Anon's Blog"
|
SAMPU_TITLE="Anon's Blog"
|
||||||
|
SAMPU_BASEURL="http://localhost:3000"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
cabal-version: 3.0
|
cabal-version: 3.0
|
||||||
name: sampu
|
name: sampu
|
||||||
version: 0.5.0
|
version: 0.6.0
|
||||||
license: ISC
|
license: ISC
|
||||||
author: James Eversole
|
author: James Eversole
|
||||||
maintainer: james@eversole.co
|
maintainer: james@eversole.co
|
||||||
@ -28,7 +28,6 @@ executable sampu
|
|||||||
, time >= 1.12.0
|
, time >= 1.12.0
|
||||||
, twain >= 2.1.0.0
|
, twain >= 2.1.0.0
|
||||||
, wai-extra >= 3.0 && < 3.2
|
, wai-extra >= 3.0 && < 3.2
|
||||||
, wai-middleware-static >= 0.9.0
|
|
||||||
, warp == 3.3.25
|
, warp == 3.3.25
|
||||||
, xml-conduit >= 1.9.1.0
|
, xml-conduit >= 1.9.1.0
|
||||||
hs-source-dirs: src
|
hs-source-dirs: src
|
||||||
|
@ -35,11 +35,17 @@ main = do
|
|||||||
++ "All required environment variables:\n"
|
++ "All required environment variables:\n"
|
||||||
++ unlines required
|
++ unlines required
|
||||||
|
|
||||||
appPort :: IO String
|
-- The port to run the web server on
|
||||||
appPort = getEnv "APPLICATIONPORT"
|
port :: IO String
|
||||||
|
port = getEnv "SAMPU_PORT"
|
||||||
|
|
||||||
appTitle :: IO String
|
-- The site's title; used for HTML title and XML feed title
|
||||||
appTitle = getEnv "BLOGTITLE"
|
title :: IO String
|
||||||
|
title = getEnv "SAMPU_TITLE"
|
||||||
|
|
||||||
|
-- The site's public-facing base url with no trailing slash
|
||||||
|
baseUrl :: IO String
|
||||||
|
baseUrl = getEnv "SAMPU_BASEURL"
|
||||||
|
|
||||||
requiredEnvVars :: [String]
|
requiredEnvVars :: [String]
|
||||||
requiredEnvVars = [ "APPLICATIONPORT", "BLOGTITLE" ]
|
requiredEnvVars = [ "SAMPU_PORT", "SAMPU_TITLE", "SAMPU_BASEURL" ]
|
||||||
|
@ -6,8 +6,7 @@ import qualified Core.Handlers as Handle
|
|||||||
import Control.Monad ( mapM_ )
|
import Control.Monad ( mapM_ )
|
||||||
import Data.String ( fromString )
|
import Data.String ( fromString )
|
||||||
import Network.Wai.Handler.Warp ( Port, run )
|
import Network.Wai.Handler.Warp ( Port, run )
|
||||||
import Network.Wai.Middleware.RequestLogger ( logStdoutDev )
|
import Network.Wai.Middleware.RequestLogger ( logStdout, logStdoutDev )
|
||||||
import Network.Wai.Middleware.Static
|
|
||||||
import System.FilePath ( takeFileName )
|
import System.FilePath ( takeFileName )
|
||||||
|
|
||||||
|
|
||||||
@ -16,7 +15,7 @@ import Web.Twain
|
|||||||
-- Get the port to listen on from the ENV and start the webserver.
|
-- Get the port to listen on from the ENV and start the webserver.
|
||||||
main :: [FilePath] -> IO ()
|
main :: [FilePath] -> IO ()
|
||||||
main postNames = do
|
main postNames = do
|
||||||
port <- Conf.appPort
|
port <- Conf.port
|
||||||
let app = preProcessors
|
let app = preProcessors
|
||||||
++ (routes postNames)
|
++ (routes postNames)
|
||||||
++ postProcessors
|
++ postProcessors
|
||||||
@ -25,11 +24,11 @@ main postNames = do
|
|||||||
|
|
||||||
-- These Middlewares are executed before any routes are reached.
|
-- These Middlewares are executed before any routes are reached.
|
||||||
preProcessors :: [Middleware]
|
preProcessors :: [Middleware]
|
||||||
preProcessors = [ logStdoutDev ]
|
preProcessors = [logStdoutDev]
|
||||||
|
|
||||||
-- These Middlewares are executed after all other routes are exhausted
|
-- These Middlewares are executed after all other routes are exhausted
|
||||||
postProcessors :: [Middleware]
|
postProcessors :: [Middleware]
|
||||||
postProcessors = []
|
postProcessors = []
|
||||||
|
|
||||||
{- The application's core routes expressed as a list of WAI Middlewares.
|
{- The application's core routes expressed as a list of WAI Middlewares.
|
||||||
The list of post names is required so that the postsIndex handler can
|
The list of post names is required so that the postsIndex handler can
|
||||||
@ -48,7 +47,8 @@ routes postNames =
|
|||||||
|
|
||||||
-- Takes a post's name extracted from the filepath and returns a valid route
|
-- Takes a post's name extracted from the filepath and returns a valid route
|
||||||
mdFileToRoute :: FilePath -> Middleware
|
mdFileToRoute :: FilePath -> Middleware
|
||||||
mdFileToRoute postName = get (fromString $ "/posts/" ++ postName) (Handle.posts postName)
|
mdFileToRoute postName =
|
||||||
|
get (fromString $ "/posts/" ++ postName) (Handle.posts postName)
|
||||||
|
|
||||||
buildMdRoutes :: [FilePath] -> [Middleware]
|
buildMdRoutes :: [FilePath] -> [Middleware]
|
||||||
buildMdRoutes postNames = map mdFileToRoute postNames
|
buildMdRoutes postNames = map mdFileToRoute postNames
|
||||||
|
@ -21,7 +21,7 @@ import Web.Twain
|
|||||||
index :: ResponderM a
|
index :: ResponderM a
|
||||||
index = do
|
index = do
|
||||||
-- Query the system environment for the BLOGTITLE environment variable
|
-- Query the system environment for the BLOGTITLE environment variable
|
||||||
title <- liftIO Conf.appTitle
|
title <- liftIO Conf.title
|
||||||
-- Read a Commonmark Markdown file and process it to HTML
|
-- Read a Commonmark Markdown file and process it to HTML
|
||||||
homeMd <- liftIO $ mdFileToLucid "./data/posts/home.md"
|
homeMd <- liftIO $ mdFileToLucid "./data/posts/home.md"
|
||||||
-- Get the Footer content from Markdown
|
-- Get the Footer content from Markdown
|
||||||
@ -32,7 +32,7 @@ index = do
|
|||||||
-- Responds with processed Commonmark -> HTML for posts existing at app init
|
-- Responds with processed Commonmark -> HTML for posts existing at app init
|
||||||
posts :: FilePath -> ResponderM a
|
posts :: FilePath -> ResponderM a
|
||||||
posts postName = do
|
posts postName = do
|
||||||
title <- liftIO Conf.appTitle
|
title <- liftIO Conf.title
|
||||||
footerMd <- liftIO $ mdFileToLucid "./data/posts/footer.md"
|
footerMd <- liftIO $ mdFileToLucid "./data/posts/footer.md"
|
||||||
postMd <- liftIO $ mdFileToLucid ("./data/posts/" ++ postName ++ ".md")
|
postMd <- liftIO $ mdFileToLucid ("./data/posts/" ++ postName ++ ".md")
|
||||||
sendLucidFragment $ basePage title (basePost postMd) footerMd
|
sendLucidFragment $ basePage title (basePost postMd) footerMd
|
||||||
@ -40,45 +40,46 @@ posts postName = do
|
|||||||
-- Builds an index of all posts on filesystem as of application init
|
-- Builds an index of all posts on filesystem as of application init
|
||||||
postsIndex :: [FilePath] -> ResponderM a
|
postsIndex :: [FilePath] -> ResponderM a
|
||||||
postsIndex postNames = do
|
postsIndex postNames = do
|
||||||
title <- liftIO Conf.appTitle
|
title <- liftIO Conf.title
|
||||||
footerMd <- liftIO $ mdFileToLucid "./data/posts/footer.md"
|
footerMd <- liftIO $ mdFileToLucid "./data/posts/footer.md"
|
||||||
sendLucidFragment $ basePage title (postIndex postNames) footerMd
|
sendLucidFragment $ basePage title (postIndex postNames) footerMd
|
||||||
|
|
||||||
-- Generates the XML feed at /feed
|
-- Generates the XML feed at /feed
|
||||||
feed :: [FilePath] -> ResponderM a
|
feed :: [FilePath] -> ResponderM a
|
||||||
feed postNames = do
|
feed postNames = do
|
||||||
title <- liftIO Conf.appTitle
|
title <- liftIO Conf.title
|
||||||
|
baseUrl <- liftIO Conf.baseUrl
|
||||||
time <- liftIO $ fmap (\x -> timeFormat x) getCurrentTime
|
time <- liftIO $ fmap (\x -> timeFormat x) getCurrentTime
|
||||||
-- Create Atom [Post] to populate the feed
|
-- Create Atom [Post] to populate the feed
|
||||||
feedData <- liftIO $ mapM makePost postNames
|
feedData <- liftIO $ mapM (makePost baseUrl) postNames
|
||||||
-- Send an XML response with an automatically populated Atom feed
|
-- Send an XML response with an automatically populated Atom feed
|
||||||
send $ xml $ LTE.encodeUtf8 $ renderFeed
|
send $ xml $ LTE.encodeUtf8 $ renderFeed
|
||||||
$ autoFeed (baseFeed title time) feedData
|
$ autoFeed (baseFeed title time baseUrl) feedData
|
||||||
where
|
where
|
||||||
-- Base feed data structure which we populate with entries
|
-- Base feed data structure which we populate with entries
|
||||||
baseFeed :: String -> String -> Atom.Feed
|
baseFeed :: String -> String -> String -> Atom.Feed
|
||||||
baseFeed title time = Atom.nullFeed
|
baseFeed title time baseUrl = Atom.nullFeed
|
||||||
"https://eversole.co/feed"
|
(pack $ baseUrl ++ "/feed")
|
||||||
(Atom.TextString $ pack title)
|
(Atom.TextString $ pack title)
|
||||||
(pack $ time ++ " UTC")
|
(pack $ time ++ " UTC")
|
||||||
|
|
||||||
-- Create an Atom Post for each markdown post present
|
-- Create an Atom Post for each markdown post present
|
||||||
makePost :: FilePath -> IO (Post)
|
makePost :: String -> FilePath -> IO (Post)
|
||||||
makePost x = do
|
makePost baseUrl postName = do
|
||||||
date <- getModificationTime $ "./data/posts/" ++ x ++ ".md"
|
date <- getModificationTime $ "./data/posts/" ++ postName ++ ".md"
|
||||||
return $ Post
|
return $ Post
|
||||||
(pack $ (timeFormat date) ++ " UTC")
|
(pack $ (timeFormat date) ++ " UTC")
|
||||||
(pack $ "https://eversole.co/posts/" ++ x)
|
(pack $ baseUrl ++ "/posts/" ++ postName)
|
||||||
(pack $ show x)
|
(pack $ show postName)
|
||||||
|
|
||||||
-- YYYY-MM-DD HH:MM | 2024-02-24 16:36
|
-- YYYY-MM-DD HH:MM | 2024-02-24 16:36
|
||||||
timeFormat :: UTCTime -> String
|
timeFormat :: UTCTime -> String
|
||||||
timeFormat x = formatTime defaultTimeLocale "%Y-%m-%d %H:%M" x
|
timeFormat date = formatTime defaultTimeLocale "%Y-%m-%d %H:%M" date
|
||||||
|
|
||||||
-- Refer to index comments
|
-- Refer to index comments
|
||||||
contact :: ResponderM a
|
contact :: ResponderM a
|
||||||
contact = do
|
contact = do
|
||||||
title <- liftIO Conf.appTitle
|
title <- liftIO Conf.title
|
||||||
contactMd <- liftIO $ mdFileToLucid "./data/posts/contact.md"
|
contactMd <- liftIO $ mdFileToLucid "./data/posts/contact.md"
|
||||||
footerMd <- liftIO $ mdFileToLucid "./data/posts/footer.md"
|
footerMd <- liftIO $ mdFileToLucid "./data/posts/footer.md"
|
||||||
sendLucidFragment $ basePage title (baseContact contactMd) footerMd
|
sendLucidFragment $ basePage title (baseContact contactMd) footerMd
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
module Core.Styles where
|
module Core.Styles where
|
||||||
|
|
||||||
import Clay hiding (main_)
|
import Clay hiding (main_)
|
||||||
import qualified Clay.Media as M
|
import qualified Clay.Media as M
|
||||||
import Data.Text.Lazy hiding (center)
|
import Data.Text.Lazy hiding (center)
|
||||||
import Prelude hiding (div)
|
import Prelude hiding (div)
|
||||||
|
|
||||||
@ -32,22 +32,22 @@ core_ = do
|
|||||||
|
|
||||||
a_ :: Css
|
a_ :: Css
|
||||||
a_ = do
|
a_ = do
|
||||||
a ? do
|
a ? do
|
||||||
textDecoration none
|
textDecoration none
|
||||||
color terColor
|
color terColor
|
||||||
|
|
||||||
body_ :: Css
|
body_ :: Css
|
||||||
body_ = do
|
body_ = do
|
||||||
body ? do
|
body ? do
|
||||||
fontFamily [] [monospace]
|
fontFamily [] [monospace]
|
||||||
fontSize $ em 1.25
|
fontSize $ em 1.25
|
||||||
fontWeight $ weight 300
|
fontWeight $ weight 300
|
||||||
textAlign start
|
textAlign start
|
||||||
margin (em 0) auto (em 0) auto
|
margin (em 0) auto (em 0) auto
|
||||||
strong ? do
|
strong ? do
|
||||||
fontWeight $ weight 600
|
fontWeight $ weight 600
|
||||||
li ? do
|
li ? do
|
||||||
listStyleType $ other "~> "
|
listStyleType $ other "\"~> \""
|
||||||
|
|
||||||
footer_ :: Css
|
footer_ :: Css
|
||||||
footer_ = do
|
footer_ = do
|
||||||
@ -105,12 +105,11 @@ nav_ = do
|
|||||||
margin (em 1.5) (em 0) (em 1.5) (em 0)
|
margin (em 1.5) (em 0) (em 1.5) (em 0)
|
||||||
width $ pct 100
|
width $ pct 100
|
||||||
textAlign center
|
textAlign center
|
||||||
".mainNav" ? do
|
".mainNav" ? do
|
||||||
margin (em 0) auto (em 0) auto
|
margin (em 0) auto (em 0) auto
|
||||||
padding (em 0) (em 0) (em 0) (em 0)
|
padding (em 0) (em 0) (em 0) (em 0)
|
||||||
overflow hidden
|
overflow hidden
|
||||||
boxShadow . pure $ bsColor "#ccc" $
|
boxShadow . pure $ bsColor "#ccc" $ shadowWithBlur (px 4) (px 4) (px 6)
|
||||||
shadowWithBlur (px 4) (px 4) (px 6)
|
|
||||||
display inlineFlex
|
display inlineFlex
|
||||||
li ? do
|
li ? do
|
||||||
listStyleType none
|
listStyleType none
|
||||||
|
Loading…
x
Reference in New Issue
Block a user