diff --git a/hledger-web/.ghci b/hledger-web/.ghci new file mode 100644 index 000000000..eaa2c9423 --- /dev/null +++ b/hledger-web/.ghci @@ -0,0 +1,2 @@ +:set -i.:config:dist/build/autogen +:set -XCPP -XTemplateHaskell -XQuasiQuotes -XTypeFamilies -XFlexibleContexts -XGADTs -XOverloadedStrings -XMultiParamTypeClasses -XGeneralizedNewtypeDeriving -XEmptyDataDecls diff --git a/hledger-web/Application.hs b/hledger-web/Application.hs new file mode 100644 index 000000000..a39ea9bf2 --- /dev/null +++ b/hledger-web/Application.hs @@ -0,0 +1,54 @@ +{-# OPTIONS_GHC -fno-warn-orphans #-} +module Application + ( makeApplication + , getApplicationDev + , makeFoundation + ) where + +import Import +import Yesod.Default.Config +import Yesod.Default.Main +import Yesod.Default.Handlers +import Network.Wai.Middleware.RequestLogger (logStdout, logStdoutDev) +import Network.HTTP.Conduit (newManager, def) + +-- Import all relevant handler modules here. +-- Don't forget to add new modules to your cabal file! +-- import Handler.Home +import Handler.Handlers + +import Hledger.Web.Options + +-- This line actually creates our YesodDispatch instance. It is the second half +-- of the call to mkYesodData which occurs in Foundation.hs. Please see the +-- comments there for more details. +mkYesodDispatch "App" resourcesApp + +-- This function allocates resources (such as a database connection pool), +-- performs initialization and creates a WAI application. This is also the +-- place to put your migrate statements to have automatic database +-- migrations handled by Yesod. +makeApplication :: AppConfig DefaultEnv Extra -> IO Application +makeApplication conf = do + foundation <- makeFoundation conf + app <- toWaiAppPlain foundation + return $ logWare app + where + logWare = if development then logStdoutDev + else logStdout + +makeFoundation :: AppConfig DefaultEnv Extra -> IO App +makeFoundation conf = do + manager <- newManager def + s <- staticSite + return $ App conf s manager + defwebopts + +-- for yesod devel +getApplicationDev :: IO (Int, Application) +getApplicationDev = + defaultDevelApp loader makeApplication + where + loader = loadConfig (configSettings Development) + { csParseExtra = parseExtra + } diff --git a/hledger-web/Foundation.hs b/hledger-web/Foundation.hs new file mode 100644 index 000000000..74f01d40f --- /dev/null +++ b/hledger-web/Foundation.hs @@ -0,0 +1,158 @@ +{- + +Define the web application's foundation, in the usual Yesod style. +See a default Yesod app's comments for more details of each part. + +-} +module Foundation where + +import Prelude +import Yesod +import Yesod.Static +import Yesod.Default.Config +#ifndef DEVELOPMENT +import Yesod.Default.Util (addStaticContentExternal) +#endif +import Network.HTTP.Conduit (Manager) +-- import qualified Settings +import Settings.Development (development) +import Settings.StaticFiles +import Settings ({-widgetFile,-} Extra (..), staticDir) +#ifndef DEVELOPMENT +import Text.Jasmine (minifym) +#endif +import Web.ClientSession (getKey) +-- import Text.Hamlet (hamletFile) + +import Hledger.Web.Options +-- import Hledger.Web.Settings +-- import Hledger.Web.Settings.StaticFiles + + +-- | The site argument for your application. This can be a good place to +-- keep settings and values requiring initialization before your application +-- starts running, such as database connections. Every handler will have +-- access to the data present here. +data App = App + { settings :: AppConfig DefaultEnv Extra + , getStatic :: Static -- ^ Settings for static file serving. + , httpManager :: Manager + -- + , appOpts :: WebOpts + } + +-- Set up i18n messages. See the message folder. +mkMessage "App" "messages" "en" + +-- This is where we define all of the routes in our application. For a full +-- explanation of the syntax, please see: +-- http://www.yesodweb.com/book/handler +-- +-- This function does three things: +-- +-- * Creates the route datatype AppRoute. Every valid URL in your +-- application can be represented as a value of this type. +-- * Creates the associated type: +-- type instance Route App = AppRoute +-- * Creates the value resourcesApp which contains information on the +-- resources declared below. This is used in Handler.hs by the call to +-- mkYesodDispatch +-- +-- What this function does *not* do is create a YesodSite instance for +-- App. Creating that instance requires all of the handler functions +-- for our application to be in scope. However, the handler functions +-- usually require access to the AppRoute datatype. Therefore, we +-- split these actions into two functions and place them in separate files. +mkYesodData "App" $(parseRoutesFile "config/routes") + +-- | A convenience alias. +type AppRoute = Route App + +type Form x = Html -> MForm App App (FormResult x, Widget) + +-- Please see the documentation for the Yesod typeclass. There are a number +-- of settings which can be configured by overriding methods here. +instance Yesod App where + approot = ApprootMaster $ appRoot . settings + + -- Store session data on the client in encrypted cookies, + -- default session idle timeout is 120 minutes + makeSessionBackend _ = do + key <- getKey "config/client_session_key.aes" + return . Just $ clientSessionBackend key 120 + + -- defaultLayout widget = do + -- master <- getYesod + -- mmsg <- getMessage + + -- -- We break up the default layout into two components: + -- -- default-layout is the contents of the body tag, and + -- -- default-layout-wrapper is the entire page. Since the final + -- -- value passed to hamletToRepHtml cannot be a widget, this allows + -- -- you to use normal widget features in default-layout. + + -- pc <- widgetToPageContent $ do + -- $(widgetFile "normalize") + -- addStylesheet $ StaticR css_bootstrap_css + -- $(widgetFile "default-layout") + -- hamletToRepHtml $(hamletFile "templates/default-layout-wrapper.hamlet") + + defaultLayout widget = do + pc <- widgetToPageContent $ do + widget + hamletToRepHtml [hamlet| +$doctype 5 + +
+