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