@@ -16,8 +16,10 @@ module Obelisk.Backend
1616 , serveDefaultObeliskApp
1717 , prettifyOutput
1818 , runBackend
19+ , configureFrontend
1920 ) where
2021
22+import Control.Monad
2123import Control.Monad.Except
2224import qualified Data.ByteString.Char8 as BSC8
2325import Data.Default (Default (..))
@@ -26,13 +28,17 @@ import Data.Functor.Sum
2628import Data.Functor.Identity
2729import Data.Text (Text)
2830import qualified Data.Text as T
31+import qualified Data.Text.IO as T
2932import Data.Text.Encoding
3033import Obelisk.Asset.Serve.Snap (serveAsset)
34+import Obelisk.ExecutableConfig.Inject (injectPure)
3135import Obelisk.Frontend
3236import Obelisk.Route
3337import Snap (MonadSnap, Snap, commandLineConfig, defaultConfig, getsRequest, httpServe, rqPathInfo,
3438 rqQueryString, writeBS, writeText)
3539import Snap.Internal.Http.Server.Config (Config (accessLog, errorLog), ConfigLog (ConfigIoLog))
40+import System.Directory
41+import System.FilePath
3642import System.IO (BufferMode (..), hSetBuffering, stderr, stdout)
3743
3844data Backend backendRoute frontendRoute = Backend
@@ -149,7 +155,7 @@ data GhcjsAppRoute :: (* -> *) -> * -> * where
149155serveGhcjsApp :: MonadSnap m => GhcjsApp (R appRouteComponent) -> R (GhcjsAppRoute appRouteComponent) -> m ()
150156serveGhcjsApp app = \case
151157 GhcjsAppRoute_App appRouteComponent :=> Identity appRouteRest ->
152− writeBS <=< liftIO $ renderFrontendHtml (appRouteComponent :/ appRouteRest) $ ghcjsFrontend $ _ghcjsApp_value app
158+ writeBS <=< liftIO $ renderFrontendHtml (appRouteComponent :/ appRouteRest) <=< configureFrontend $ ghcjsFrontend $ _ghcjsApp_value app
153159 GhcjsAppRoute_Resource :=> Identity pathSegments -> serveStaticAssets (_ghcjsApp_compiled app) pathSegments
154160
155161runBackend :: Backend fullRoute frontendRoute -> Frontend (R frontendRoute) -> IO ()
@@ -162,3 +168,21 @@ runBackend backend frontend = case checkEncoder $ _backend_routeEncoder backend
162168 Right r -> case r of
163169 InL backendRoute :=> Identity a -> serveRoute $ backendRoute :/ a
164170 InR obeliskRoute :=> Identity a -> serveDefaultObeliskApp frontend $ obeliskRoute :/ a
171+
172+configureFrontend :: Frontend a -> IO (Frontend a)
173+configureFrontend f = do
174+ cfgC <- getConfigs "config/common"
175+ cfgF <- getConfigs "config/frontend"
176+ return $ f { _frontend_head = _frontend_head f >> mapM_ (uncurry injectPure) (cfgC <> cfgF) }
177+ where
178+ getConfigs :: FilePath -> IO [(FilePath, Text)]
179+ getConfigs fp = do
180+ ps <- listDirectory fp
181+ fmap concat $ forM ps $ \p -> do
182+ let fullpath = fp </> p
183+ dir <- doesDirectoryExist p
184+ if dir
185+ then getConfigs fullpath
186+ else do
187+ v <- T.readFile fullpath
188+ return [(fullpath, v)]