Stop hardcoding feed URL; update environment variable helper function names and add new SAMPU_BASEURL env var
This commit is contained in:
		| @ -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 | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user