packages feed

yesod-bin 1.4.0.9 → 1.4.1

raw patch · 8 files changed

+2418/−2958 lines, 8 files

Files

ChangeLog.md view
@@ -1,5 +1,15 @@-__1.4.0.9__ Allow devel.hs to be located in app/ or src/ subdirectories.+## 1.4.1 -__1.4.0.8__ Updated postgres-fay scaffolding for yesod-fay 0.7.0+Significant update to the scaffolding. -__1.4.0.7__ Fix a bug in `yesod devel` when cabal config has `tests: True` #864+## 1.4.0.9++Allow devel.hs to be located in app/ or src/ subdirectories.++## 1.4.0.8++Updated postgres-fay scaffolding for yesod-fay 0.7.0++## 1.4.0.7++Fix a bug in `yesod devel` when cabal config has `tests: True` #864
hsfiles/mongo.hsfiles view
@@ -28,30 +28,29 @@ {-# START_FILE Application.hs #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Application-    ( makeApplication-    , getApplicationDev+    ( getApplicationDev+    , appMain+    , develMain     , makeFoundation     ) where +import Control.Monad.Logger                 (liftLoc) import Import-import Settings-import Yesod.Auth-import Yesod.Default.Config-import Yesod.Default.Main-import Yesod.Default.Handlers-import Network.Wai.Middleware.RequestLogger-    ( mkRequestLogger, outputFormat, OutputFormat (..), IPAddrSource (..), destination-    )-import qualified Network.Wai.Middleware.RequestLogger as RequestLogger-import qualified Database.Persist-import Network.HTTP.Client.Conduit (newManager)-import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize)-import Network.Wai.Logger (clockDateCacher)-import Data.Default (def)-import Yesod.Core.Types (loggerSet, Logger (Logger))+import Language.Haskell.TH.Syntax           (qLocation)+import Network.Wai.Handler.Warp             (Settings, defaultSettings,+                                             defaultShouldDisplayException,+                                             runSettings, setHost,+                                             setOnException, setPort)+import Network.Wai.Middleware.RequestLogger (Destination (Logger),+                                             IPAddrSource (..),+                                             OutputFormat (..), destination,+                                             mkRequestLogger, outputFormat)+import System.Log.FastLogger                (defaultBufSize, newStdoutLoggerSet,+                                             toLogStr)  -- Import all relevant handler modules here. -- Don't forget to add new modules to your cabal file!+import Handler.Common import Handler.Home  -- This line actually creates our YesodDispatch instance. It is the second half@@ -59,103 +58,122 @@ -- 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+-- | This function allocates resources (such as a database connection pool),+-- performs initialization and return a foundation datatype value. This is also+-- the place to put your migrate statements to have automatic database -- migrations handled by Yesod.-makeApplication :: AppConfig DefaultEnv Extra -> IO (Application, LogFunc)-makeApplication conf = do-    foundation <- makeFoundation conf+makeFoundation :: AppSettings -> IO App+makeFoundation appSettings = do+    -- Some basic initializations: HTTP connection manager, logger, and static+    -- subsite.+    appHttpManager <- newManager+    appLogger <- newStdoutLoggerSet defaultBufSize >>= makeYesodLogger+    appStatic <-+        (if appMutableStatic appSettings then staticDevel else static)+        (appStaticDir appSettings) -    -- Initialize the logging middleware+    -- Create the database connection pool+    appConnPool <- createPoolConfig $ appDatabaseConf appSettings++    -- Return the foundation+    return App {..}++-- | Convert our foundation to a WAI Application by calling @toWaiAppPlain@ and+-- applyng some additional middlewares.+makeApplication :: App -> IO Application+makeApplication foundation = do     logWare <- mkRequestLogger def         { outputFormat =-            if development+            if appDetailedRequestLogging $ appSettings foundation                 then Detailed True-                else Apache FromSocket-        , destination = RequestLogger.Logger $ loggerSet $ appLogger foundation+                else Apache+                        (if appIpFromHeader $ appSettings foundation+                            then FromFallback+                            else FromSocket)+        , destination = Logger $ loggerSet $ appLogger foundation         }      -- Create the WAI application and apply middlewares-    app <- toWaiAppPlain foundation-    let logFunc = messageLoggerSource foundation (appLogger foundation)-    return (logWare $ defaultMiddlewaresNoLogging app, logFunc)+    appPlain <- toWaiAppPlain foundation+    return $ logWare $ defaultMiddlewaresNoLogging appPlain --- | Loads up any necessary settings, creates your foundation datatype, and--- performs some initialization.-makeFoundation :: AppConfig DefaultEnv Extra -> IO App-makeFoundation conf = do-    manager <- newManager-    s <- staticSite-    dbconf <- withYamlEnvironment "config/mongoDB.yml" (appEnv conf)-              Database.Persist.loadConfig >>=-              Database.Persist.applyEnv-    p <- Database.Persist.createPoolConfig (dbconf :: Settings.PersistConf)+-- | Warp settings for the given foundation value.+warpSettings :: App -> Settings+warpSettings foundation =+      setPort (appPort $ appSettings foundation)+    $ setHost (appHost $ appSettings foundation)+    $ setOnException (\_req e ->+        when (defaultShouldDisplayException e) $ messageLoggerSource+            foundation+            (appLogger foundation)+            $(qLocation >>= liftLoc)+            "yesod"+            LevelError+            (toLogStr $ "Exception from Warp: " ++ show e))+      defaultSettings -    loggerSet' <- newStdoutLoggerSet defaultBufSize-    (getter, _) <- clockDateCacher+-- | For yesod devel, return the Warp settings and WAI Application.+getApplicationDev :: IO (Settings, Application)+getApplicationDev = do+    settings <- loadAppSettings [configSettingsYml] [] useEnv+    foundation <- makeFoundation settings+    app <- makeApplication foundation+    wsettings <- getDevSettings $ warpSettings foundation+    return (wsettings, app) -    let logger = Yesod.Core.Types.Logger loggerSet' getter-        foundation = App-            { settings = conf-            , getStatic = s-            , connPool = p-            , httpManager = manager-            , persistConfig = dbconf-            , appLogger = logger-            }+-- | main function for use by yesod devel+develMain :: IO ()+develMain = develMainHelper getApplicationDev -    return foundation+-- | The @main@ function for an executable running this site.+appMain :: IO ()+appMain = do+    -- Get the settings from all relevant sources+    settings <- loadAppSettingsArgs+        -- fall back to compile-time values, set to [] to require values at runtime+        [configSettingsYmlValue] --- for yesod devel-getApplicationDev :: IO (Int, Application)-getApplicationDev =-    defaultDevelApp loader (fmap fst . makeApplication)-  where-    loader = Yesod.Default.Config.loadConfig (configSettings Development)-        { csParseExtra = parseExtra-        }+        -- allow environment variables to override+        useEnv +    -- Generate the foundation from the settings+    foundation <- makeFoundation settings++    -- Generate a WAI Application from the foundation+    app <- makeApplication foundation++    -- Run the application with Warp+    runSettings (warpSettings foundation) app+ {-# START_FILE Foundation.hs #-} module Foundation where -import Prelude-import Yesod-import Yesod.Static-import Yesod.Auth-import Yesod.Auth.BrowserId-import Yesod.Default.Config-import Yesod.Default.Util (addStaticContentExternal)-import Network.HTTP.Client.Conduit (Manager, HasHttpManager (getHttpManager))-import qualified Settings-import Settings.Development (development)-import qualified Database.Persist-import Settings.StaticFiles+import ClassyPrelude.Yesod import Database.Persist.MongoDB hiding (master)-import Settings (widgetFile, Extra (..)) import Model-import Text.Jasmine (minifym)-import Text.Hamlet (hamletFile)-import Yesod.Core.Types (Logger)+import Settings+import Settings.StaticFiles+import Text.Hamlet              (hamletFile)+import Text.Jasmine             (minifym)+import Yesod.Auth+import Yesod.Auth.BrowserId     (authBrowserId)+import Yesod.Core.Types         (Logger)+import Yesod.Default.Util       (addStaticContentExternal) --- | The site argument for your application. This can be a good place to+-- | The foundation datatype 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.-    , connPool :: Database.Persist.PersistConfigPool Settings.PersistConf -- ^ Database connection pool.-    , httpManager :: Manager-    , persistConfig :: Settings.PersistConf-    , appLogger :: Logger+    { appSettings    :: AppSettings+    , appStatic      :: Static -- ^ Settings for static file serving.+    , appConnPool    :: ConnectionPool -- ^ Database connection pool.+    , appHttpManager :: Manager+    , appLogger      :: Logger     }  instance HasHttpManager App where-    getHttpManager = httpManager---- Set up i18n messages. See the message folder.-mkMessage "App" "messages" "en"+    getHttpManager = appHttpManager  -- This is where we define all of the routes in our application. For a full -- explanation of the syntax, please see:@@ -166,12 +184,15 @@ -- explanation for this split. mkYesodData "App" $(parseRoutesFile "config/routes") +-- | A convenient synonym for creating forms. type Form x = Html -> MForm (HandlerT App IO) (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+    -- Controls the base of generated URLs. For more information on modifying,+    -- see: https://github.com/yesodweb/yesod/wiki/Overriding-approot+    approot = ApprootMaster $ appRoot . appSettings      -- Store session data on the client in encrypted cookies,     -- default session idle timeout is 120 minutes@@ -194,12 +215,6 @@             $(widgetFile "default-layout")         withUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet") -    -- This is done to provide an optimization for serving static files from-    -- a separate domain. Please see the staticRoot setting in Settings.hs-    urlRenderOverride y (StaticR s) =-        Just $ uncurry (joinPath y (Settings.staticRoot $ settings y)) $ renderRoute s-    urlRenderOverride _ _ = Nothing-     -- The page to be redirected to when authentication is required.     authRoute _ = Just $ AuthR LoginR @@ -214,28 +229,39 @@     -- and names them based on a hash of their content. This allows     -- expiration dates to be set far in the future without worry of     -- users receiving stale content.-    addStaticContent =-        addStaticContentExternal minifym genFileName Settings.staticDir (StaticR . flip StaticRoute [])+    addStaticContent ext mime content = do+        master <- getYesod+        let staticDir = appStaticDir $ appSettings master+        addStaticContentExternal+            minifym+            genFileName+            staticDir+            (StaticR . flip StaticRoute [])+            ext+            mime+            content       where         -- Generate a unique filename based on the content itself-        genFileName lbs-            | development = "autogen-" ++ base64md5 lbs-            | otherwise   = base64md5 lbs--    -- Place Javascript at bottom of the body tag so the rest of the page loads first-    jsLoader _ = BottomOfBody+        genFileName lbs = "autogen-" ++ base64md5 lbs      -- What messages should be logged. The following includes all messages when     -- in development, and warnings and errors in production.-    shouldLog _ _source level =-        development || level == LevelWarn || level == LevelError+    shouldLog app _source level =+        appShouldLogAll (appSettings app)+            || level == LevelWarn+            || level == LevelError      makeLogger = return . appLogger  -- How to run database actions. instance YesodPersist App where     type YesodPersistBackend App = MongoContext-    runDB = defaultRunDB persistConfig connPool+    runDB action = do+        master <- getYesod+        runMongoDBPool+            (mgAccessMode $ appDatabaseConf $ appSettings master)+            action+            (appConnPool master)  instance YesodAuth App where     type AuthId App = UserId@@ -244,6 +270,8 @@     loginDest _ = HomeR     -- Where to send a user after logout     logoutDest _ = HomeR+    -- Override the above two destinations when a Referer: header is present+    redirectToReferer _ = True      getAuthId creds = runDB $ do         x <- getBy $ UniqueUser $ credsIdent creds@@ -258,7 +286,7 @@     -- You can add other plugins like BrowserID, email or OAuth here     authPlugins _ = [authBrowserId def] -    authHttpManager = httpManager+    authHttpManager = getHttpManager  instance YesodAuthPersist App @@ -267,23 +295,38 @@ instance RenderMessage App FormMessage where     renderMessage _ _ = defaultFormMessage --- | Get the 'Extra' value, used to hold data from the settings.yml file.-getExtra :: Handler Extra-getExtra = fmap (appExtra . settings) getYesod---- Note: previous versions of the scaffolding included a deliver function to--- send emails. Unfortunately, there are too many different options for us to--- give a reasonable default. Instead, the information is available on the--- wiki:+-- Note: Some functionality previously present in the scaffolding has been+-- moved to documentation in the Wiki. Following are some hopefully helpful+-- links: -- -- https://github.com/yesodweb/yesod/wiki/Sending-email+-- https://github.com/yesodweb/yesod/wiki/Serve-static-files-from-a-separate-domain+-- https://github.com/yesodweb/yesod/wiki/i18n-messages-in-the-scaffolding +{-# START_FILE Handler/Common.hs #-}+-- | Common handler functions.+module Handler.Common where++import Data.FileEmbed (embedFile)+import Import++-- These handlers embed files in the executable at compile time to avoid a+-- runtime dependency, and for efficiency.++getFaviconR :: Handler TypedContent+getFaviconR = return $ TypedContent "image/x-icon"+                     $ toContent $(embedFile "config/favicon.ico")++getRobotsR :: Handler TypedContent+getRobotsR = return $ TypedContent typePlain+                    $ toContent $(embedFile "config/robots.txt")+ {-# START_FILE Handler/Home.hs #-} module Handler.Home where  import Import-import Yesod.Form.Bootstrap3-    ( BootstrapFormLayout (..), renderBootstrap3, withSmallInput )+import Yesod.Form.Bootstrap3 (BootstrapFormLayout (..), renderBootstrap3,+                              withSmallInput)  -- This is a handler function for the GET request method on the HomeR -- resource pattern. All of your resource patterns are defined in@@ -325,42 +368,22 @@     ( module Import     ) where -import           Prelude              as Import hiding (head, init, last,-                                                 readFile, tail, writeFile)-import           Yesod                as Import hiding (Route (..))--import           Control.Applicative  as Import (pure, (<$>), (<*>))-import           Data.Text            as Import (Text)--import           Foundation           as Import-import           Model                as Import-import           Settings             as Import-import           Settings.Development as Import-import           Settings.StaticFiles as Import--#if __GLASGOW_HASKELL__ >= 704-import           Data.Monoid          as Import-                                                 (Monoid (mappend, mempty, mconcat),-                                                 (<>))-#else-import           Data.Monoid          as Import-                                                 (Monoid (mappend, mempty, mconcat))--infixr 5 <>-(<>) :: Monoid m => m -> m -> m-(<>) = mappend-#endif+import ClassyPrelude.Yesod   as Import+import Foundation            as Import+import Model                 as Import+import Settings              as Import+import Settings.StaticFiles  as Import+import Yesod.Auth            as Import+import Yesod.Core.Types      as Import (loggerSet)+import Yesod.Default.Config2 as Import  {-# START_FILE Model.hs #-} module Model where -import Yesod-import Data.Text (Text)+import ClassyPrelude.Yesod import Database.Persist.Quasi import Database.Persist.MongoDB hiding (master) import Language.Haskell.TH.Syntax-import Data.Typeable (Typeable)-import Prelude  -- You can define all of your database entities in the entities file. -- You can find more information on persistent and how to declare entities@@ -391,7 +414,7 @@                      Model                      Settings                      Settings.StaticFiles-                     Settings.Development+                     Handler.Common                      Handler.Home      if flag(dev) || flag(library-only)@@ -415,17 +438,21 @@                 DeriveDataTypeable                 ViewPatterns                 TupleSections+                RecordWildCards      build-depends: base                          >= 4          && < 5-                 , yesod                         >= 1.4.0      && < 1.5+                 , yesod                         >= 1.4.1      && < 1.5                  , yesod-core                    >= 1.4.0      && < 1.5                  , yesod-auth                    >= 1.4.0      && < 1.5-                 , yesod-static                  >= 1.4.0      && < 1.5+                 , yesod-static                  >= 1.4.0.3    && < 1.5                  , yesod-form                    >= 1.4.0      && < 1.5+                 , classy-prelude                >= 0.10.2+                 , classy-prelude-conduit        >= 0.10.2+                 , classy-prelude-yesod          >= 0.10.2                  , bytestring                    >= 0.9        && < 0.11                  , text                          >= 0.11       && < 2.0                  , persistent                    >= 2.0        && < 2.2-                 , persistent-mongoDB            >= 2.0        && < 2.2+                 , persistent-mongoDB            >= 2.1.2      && < 2.2                  , persistent-template           >= 2.0        && < 2.2                  , template-haskell                  , shakespeare                   >= 2.0        && < 2.1@@ -442,10 +469,12 @@                  , monad-logger                  >= 0.3        && < 0.4                  , fast-logger                   >= 2.2        && < 2.3                  , wai-logger                    >= 2.2        && < 2.3--    -- see https://github.com/yesodweb/yesod/issues/814-    if !os(windows)-        build-depends: unix+                 , file-embed+                 , safe+                 , unordered-containers+                 , containers+                 , vector+                 , time  executable         PROJECTNAME     if flag(library-only)@@ -453,9 +482,7 @@      main-is:           main.hs     hs-source-dirs:    app-    build-depends:     base-                     , PROJECTNAME-                     , yesod+    build-depends:     base, PROJECTNAME      ghc-options:       -threaded -O2 -rtsopts -with-rtsopts=-N @@ -483,7 +510,7 @@      build-depends: base                  , PROJECTNAME-                 , yesod-test >= 1.4 && < 1.5+                 , yesod-test >= 1.4.2 && < 1.5                  , yesod-core                  , yesod                  , persistent@@ -492,6 +519,8 @@                  , monad-logger                  , transformers                  , hspec+                 , classy-prelude+                 , classy-prelude-yesod  {-# START_FILE Settings.hs #-} -- | Settings are centralized, as much as possible, into this file. This@@ -501,45 +530,81 @@ -- declared in the Foundation.hs file. module Settings where -import Prelude-import Text.Shakespeare.Text (st)-import Language.Haskell.TH.Syntax-import Database.Persist.MongoDB (MongoConf)-import Yesod.Default.Config-import Yesod.Default.Util-import Data.Text (Text)-import Data.Yaml-import Control.Applicative-import Settings.Development-import Data.Default (def)-import Text.Hamlet+import ClassyPrelude.Yesod+import Control.Exception           (throw)+import Data.Aeson                  (Result (..), fromJSON, withObject, (.!=),+                                    (.:?))+import Data.FileEmbed              (embedFile)+import Data.Yaml                   (decodeEither')+import Database.Persist.MongoDB    (MongoConf)+import Language.Haskell.TH.Syntax  (Exp, Name, Q)+import Network.Wai.Handler.Warp    (HostPreference)+import Yesod.Default.Config2       (applyEnvValue, configSettingsYml)+import Yesod.Default.Util          (WidgetFileSettings, widgetFileNoReload,+                                    widgetFileReload) --- | Which Persistent backend this site is using.-type PersistConf = MongoConf+-- | Runtime settings to configure this application. These settings can be+-- loaded from various sources: defaults, environment variables, config files,+-- theoretically even a database.+data AppSettings = AppSettings+    { appStaticDir              :: String+    -- ^ Directory from which to serve static files.+    , appDatabaseConf           :: MongoConf+    -- ^ Configuration settings for accessing the database.+    , appRoot                   :: Text+    -- ^ Base for all generated URLs.+    , appHost                   :: HostPreference+    -- ^ Host/interface the server should bind to.+    , appPort                   :: Int+    -- ^ Port to listen on+    , appIpFromHeader           :: Bool+    -- ^ Get the IP address from the header when logging. Useful when sitting+    -- behind a reverse proxy. --- Static setting below. Changing these requires a recompile+    , appDetailedRequestLogging :: Bool+    -- ^ Use detailed request logging system+    , appShouldLogAll           :: Bool+    -- ^ Should all log messages be displayed?+    , appReloadTemplates        :: Bool+    -- ^ Use the reload version of templates+    , appMutableStatic          :: Bool+    -- ^ Assume that files in the static dir may change after compilation+    , appSkipCombining          :: Bool+    -- ^ Perform no stylesheet/script combining --- | The location of static files on your system. This is a file system--- path. The default value works properly with your scaffolded site.-staticDir :: FilePath-staticDir = "static"+    -- Example app-specific configuration values.+    , appCopyright              :: Text+    -- ^ Copyright text to appear in the footer of the page+    , appAnalytics              :: Maybe Text+    -- ^ Google Analytics code+    } --- | The base URL for your static files. As you can see by the default--- value, this can simply be "static" appended to your application root.--- A powerful optimization can be serving static files from a separate--- domain name. This allows you to use a web server optimized for static--- files, more easily set expires and cache values, and avoid possibly--- costly transference of cookies on static files. For more information,--- please see:---   http://code.google.com/speed/page-speed/docs/request.html#ServeFromCookielessDomain------ If you change the resource pattern for StaticR in Foundation.hs, you will--- have to make a corresponding change here.------ To see how this value is used, see urlRenderOverride in Foundation.hs-staticRoot :: AppConfig DefaultEnv x -> Text-staticRoot conf = [st|#{appRoot conf}/static|]+instance FromJSON AppSettings where+    parseJSON = withObject "AppSettings" $ \o -> do+        let defaultDev =+#if DEVELOPMENT+                True+#else+                False+#endif+        appStaticDir              <- o .: "static-dir"+        appDatabaseConf           <- o .: "database"+        appRoot                   <- o .: "approot"+        appHost                   <- fromString <$> o .: "host"+        appPort                   <- o .: "port"+        appIpFromHeader           <- o .: "ip-from-header" +        appDetailedRequestLogging <- o .:? "detailed-logging" .!= defaultDev+        appShouldLogAll           <- o .:? "should-log-all"   .!= defaultDev+        appReloadTemplates        <- o .:? "reload-templates" .!= defaultDev+        appMutableStatic          <- o .:? "mutable-static"   .!= defaultDev+        appSkipCombining          <- o .:? "skip-combining"   .!= defaultDev++        appCopyright              <- o .: "copyright"+        appAnalytics              <- o .:? "analytics"++        return AppSettings {..}+ -- | Settings for 'widgetFile', such as which template languages to support and -- default Hamlet settings. --@@ -548,81 +613,62 @@ -- https://github.com/yesodweb/yesod/wiki/Overriding-widgetFile widgetFileSettings :: WidgetFileSettings widgetFileSettings = def-    { wfsHamletSettings = defaultHamletSettings-        { hamletNewlines = AlwaysNewlines-        }-    } +-- | How static files should be combined.+combineSettings :: CombineSettings+combineSettings = def+ -- The rest of this file contains settings which rarely need changing by a -- user.  widgetFile :: String -> Q Exp-widgetFile = (if development then widgetFileReload-                             else widgetFileNoReload)+widgetFile = (if appReloadTemplates compileTimeAppSettings+                then widgetFileReload+                else widgetFileNoReload)               widgetFileSettings -data Extra = Extra-    { extraCopyright :: Text-    , extraAnalytics :: Maybe Text -- ^ Google Analytics-    } deriving Show+-- | Raw bytes at compile time of @config/settings.yml@+configSettingsYmlBS :: ByteString+configSettingsYmlBS = $(embedFile configSettingsYml) -parseExtra :: DefaultEnv -> Object -> Parser Extra-parseExtra _ o = Extra-    <$> o .:  "copyright"-    <*> o .:? "analytics"+-- | @config/settings.yml@, parsed to a @Value@.+configSettingsYmlValue :: Value+configSettingsYmlValue = either throw id $ decodeEither' configSettingsYmlBS -{-# START_FILE Settings/Development.hs #-}-module Settings.Development where+-- | A version of @AppSettings@ parsed at compile time from @config/settings.yml@.+compileTimeAppSettings :: AppSettings+compileTimeAppSettings =+    case fromJSON $ applyEnvValue False mempty configSettingsYmlValue of+        Error e -> error e+        Success settings -> settings -import Prelude+-- The following two functions can be used to combine multiple CSS or JS files+-- at compile time to decrease the number of http requests.+-- Sample usage (inside a Widget):+--+-- > $(combineStylesheets 'StaticR [style1_css, style2_css]) -development :: Bool-development =-#if DEVELOPMENT-  True-#else-  False-#endif+combineStylesheets :: Name -> [Route Static] -> Q Exp+combineStylesheets = combineStylesheets'+    (appSkipCombining compileTimeAppSettings)+    combineSettings -production :: Bool-production = not development+combineScripts :: Name -> [Route Static] -> Q Exp+combineScripts = combineScripts'+    (appSkipCombining compileTimeAppSettings)+    combineSettings  {-# START_FILE Settings/StaticFiles.hs #-} module Settings.StaticFiles where -import Prelude (IO)-import Yesod.Static-import qualified Yesod.Static as Static-import Settings (staticDir)-import Settings.Development-import Language.Haskell.TH (Q, Exp, Name)-import Data.Default (def)---- | use this to create your static file serving site-staticSite :: IO Static.Static-staticSite = if development then Static.staticDevel staticDir-                            else Static.static      staticDir+import Settings     (appStaticDir, compileTimeAppSettings)+import Yesod.Static (staticFiles)  -- | This generates easy references to files in the static directory at compile time, --   giving you compile-time verification that referenced files exist. --   Warning: any files added to your static directory during run-time can't be --   accessed this way. You'll have to use their FilePath or URL to access them.-$(staticFiles Settings.staticDir)--combineSettings :: CombineSettings-combineSettings = def---- The following two functions can be used to combine multiple CSS or JS files--- at compile time to decrease the number of http requests.--- Sample usage (inside a Widget):------ > $(combineStylesheets 'StaticR [style1_css, style2_css])--combineStylesheets :: Name -> [Route Static] -> Q Exp-combineStylesheets = combineStylesheets' development combineSettings--combineScripts :: Name -> [Route Static] -> Q Exp-combineScripts = combineScripts' development combineSettings+staticFiles (appStaticDir compileTimeAppSettings)  {-# START_FILE app/DevelMain.hs #-} -- | Development version to be run inside GHCi.@@ -689,19 +735,24 @@ start :: MVar () -- ^ Written to when the thread is killed.       -> IO ThreadId start done = do-    (port,app) <- getApplicationDev-    forkIO (finally (runSettings (setPort port defaultSettings) app)+    (settings,app) <- getApplicationDev+    forkIO (finally (runSettings settings app)                     (putMVar done ())) +{-# START_FILE app/devel.hs #-}+{-# LANGUAGE PackageImports #-}+import "PROJECTNAME" Application (develMain)+import Prelude (IO)++main :: IO ()+main = develMain+ {-# START_FILE app/main.hs #-}-import Prelude              (IO)-import Yesod.Default.Config (fromArgs)-import Yesod.Default.Main   (defaultMainLog)-import Settings             (parseExtra)-import Application          (makeApplication)+import Prelude     (IO)+import Application (appMain)  main :: IO ()-main = defaultMainLog (fromArgs parseExtra) makeApplication+main = appMain  {-# START_FILE BASE64 config/favicon.ico #-} AAABAAIAEBAAAAEAIABoBAAAJgAAABAQAgABAAEAsAAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAA@@ -806,37 +857,11 @@   -- By default this file is used in Model.hs (which is imported by Foundation.hs) -{-# START_FILE config/mongoDB.yml #-}-Default: &defaults-  user: PROJECTNAME-  password: PROJECTNAME-  host: localhost-  database: PROJECTNAME-  connections: 10--Development:-  <<: *defaults--Testing:-  database: PROJECTNAME_test-  <<: *defaults--Staging:-  database: PROJECTNAME_staging-  connections: 100-  <<: *defaults--Production:-  database: PROJECTNAME_production-  connections: 100-  host: localhost-  <<: *defaults- {-# START_FILE config/robots.txt #-} User-agent: *  {-# START_FILE config/routes #-}-/static StaticR Static getStatic+/static StaticR Static appStatic /auth   AuthR   Auth   getAuth  /favicon.ico FaviconR GET@@ -845,155 +870,35 @@ / HomeR GET POST  {-# START_FILE config/settings.yml #-}-Default: &defaults-  host: "*4" # any IPv4 host-  port: 3000-  approot: "http://localhost:3000"-  copyright: Insert copyright statement here-  #analytics: UA-YOURCODE--Development:-  <<: *defaults--Testing:-  <<: *defaults--Staging:-  <<: *defaults--Production:-  #approot: "http://www.example.com"-  <<: *defaults--{-# START_FILE deploy/Procfile #-}-# Free deployment to Heroku.-#-#   !! Warning: You must use a 64 bit machine to compile !!-#-#   This could mean using a virtual machine. Give your VM as much memory as you can to speed up linking.-#-# Basic Yesod setup:-#-# * Move this file out of the deploy directory and into your root directory-#-#     mv deploy/Procfile ./-#-# * Create an empty package.json-#     echo '{ "name": "PROJECTNAME", "version": "0.0.1", "dependencies": {} }' >> package.json-#-# Postgresql Yesod setup:-#-# * add dependencies on the "heroku", "aeson" and "unordered-containers" packages in your cabal file-#-# * add code in Application.hs to use the heroku package and load the connection parameters.-#   The below works for Postgresql.-#-#   import Data.HashMap.Strict as H-#   import Data.Aeson.Types as AT-#   #ifndef DEVELOPMENT-#   import qualified Web.Heroku-#   #endif-#-#-#-#   makeFoundation :: AppConfig DefaultEnv Extra -> Logger -> IO App-#   makeFoundation conf setLogger = do-#       manager <- newManager def-#       s <- staticSite-#       hconfig <- loadHerokuConfig-#       dbconf <- withYamlEnvironment "config/postgresql.yml" (appEnv conf)-#                 (Database.Persist.Store.loadConfig . combineMappings hconfig) >>=-#                 Database.Persist.Store.applyEnv-#       p <- Database.Persist.Store.createPoolConfig (dbconf :: Settings.PersistConfig)-#       Database.Persist.Store.runPool dbconf (runMigration migrateAll) p-#       return $ App conf setLogger s p manager dbconf-#-#   #ifndef DEVELOPMENT-#   canonicalizeKey :: (Text, val) -> (Text, val)-#   canonicalizeKey ("dbname", val) = ("database", val)-#   canonicalizeKey pair = pair-#-#   toMapping :: [(Text, Text)] -> AT.Value-#   toMapping xs = AT.Object $ M.fromList $ map (\(key, val) -> (key, AT.String val)) xs-#   #endif-#-#   combineMappings :: AT.Value -> AT.Value -> AT.Value-#   combineMappings (AT.Object m1) (AT.Object m2) = AT.Object $ m1 `M.union` m2-#   combineMappings _ _ = error "Data.Object is not a Mapping."-#-#   loadHerokuConfig :: IO AT.Value-#   loadHerokuConfig = do-#   #ifdef DEVELOPMENT-#       return $ AT.Object M.empty-#   #else-#       Web.Heroku.dbConnParams >>= return . toMapping . map canonicalizeKey-#   #endif--+static-dir:     "_env:STATIC_DIR:static"+host:           "_env:HOST:*4" # any IPv4 host+port:           "_env:PORT:3000"+approot:        "_env:APPROOT:http://localhost:3000"+ip-from-header: "_env:IP_FROM_HEADER:false" -# Heroku setup:-# Find the Heroku guide. Roughly:-#-# * sign up for a heroku account and register your ssh key-# * create a new application on the *cedar* stack-#-# * make your Yesod project the git repository for that application-# * create a deploy branch-#-#     git checkout -b deploy-#-# Repeat these steps to deploy:-# * add your web executable binary (referenced below) to the git repository-#-#     git checkout deploy-#     git add ./dist/build/PROJECTNAME/PROJECTNAME-#     git commit -m deploy-#-# * push to Heroku+# Optional values with the following production defaults.+# In development, they default to the inverse. #-#     git push heroku deploy:master---# Heroku configuration that runs your app-web: ./dist/build/PROJECTNAME/PROJECTNAME production -p $PORT--{-# START_FILE devel.hs #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE PackageImports #-}-import "PROJECTNAME" Application (getApplicationDev)-import Network.Wai.Handler.Warp-    (runSettings, defaultSettings, setPort)-import Control.Concurrent (forkIO)-import System.Directory (doesFileExist, removeFile)-import System.Exit (exitSuccess)-import Control.Concurrent (threadDelay)--#ifndef mingw32_HOST_OS-import System.Posix.Signals (installHandler, sigINT, Handler(Catch))-#endif--main :: IO ()-main = do-#ifndef mingw32_HOST_OS-    _ <- installHandler sigINT (Catch $ return ()) Nothing-#endif--    putStrLn "Starting devel application"-    (port, app) <- getApplicationDev-    forkIO $ runSettings (setPort port defaultSettings) app-    loop+# development: false+# detailed-logging: false+# should-log-all: false+# reload-templates: false+# mutable-static: false+# skip-combining: false -loop :: IO ()-loop = do-  threadDelay 100000-  e <- doesFileExist "yesod-devel/devel-terminate"-  if e then terminateDevel else loop+database:+  user:        "PROJECTNAME"+  password:    "PROJECTNAME"+  host:        "localhost"+  database:    "PROJECTNAME"+  connections: 10 -terminateDevel :: IO ()-terminateDevel = exitSuccess+copyright: Insert copyright statement here+#analytics: UA-YOURCODE -{-# START_FILE messages/en.msg #-}-Hello: Hello+{-# START_FILE config/test-settings.yml #-}+database:+  database: PROJECTNAME_test  {-# START_FILE static/css/bootstrap.css #-} /*!@@ -8959,9 +8864,9 @@             <div id="main" role="main">               ^{pageBody pc}             <footer>-                #{extraCopyright $ appExtra $ settings master}+                #{appCopyright $ appSettings master} -        $maybe analytics <- extraAnalytics $ appExtra $ settings master+        $maybe analytics <- appAnalytics $ appSettings master             <script>               if(!window.location.href.match(/localhost/)){                 window._gaq = [['_setAccount','#{analytics}'],['_trackPageview'],['_trackPageLoadTime']];@@ -8984,7 +8889,7 @@ ^{widget}  {-# START_FILE templates/homepage.hamlet #-}-<h1>_{MsgHello}+<h1>Welcome to Yesod!  <ol>   <li>Now that you have a working project you should use the #@@ -9035,94 +8940,92 @@     color: #990 } -{-# START_FILE test/Handler/HomeSpec.hs #-}-module Handler.HomeSpec-    ( spec-    ) where+{-# START_FILE test/Handler/CommonSpec.hs #-}+module Handler.CommonSpec (spec) where  import TestImport-import qualified Data.List as L  spec :: Spec-spec =-    ydescribe "These are some example tests" $ do--        yit "loads the index and checks it looks right" $ do-            get HomeR+spec = withApp $ do+    describe "robots.txt" $ do+        it "gives a 200" $ do+            get RobotsR             statusIs 200-            htmlAllContain "h1" "Hello"+        it "has correct User-agent" $ do+            get RobotsR+            bodyContains "User-agent: *"+    describe "favicon.ico" $ do+        it "gives a 200" $ do+            get FaviconR+            statusIs 200 -            request $ do-                setMethod "POST"-                setUrl HomeR-                addNonce-                fileByLabel "Choose a file" "test/Spec.hs" "text/plain" -- talk about self-reference-                byLabel "What's on the file?" "Some Content"+{-# START_FILE test/Handler/HomeSpec.hs #-}+module Handler.HomeSpec (spec) where -            statusIs 200-            -- more debugging printBody-            htmlCount ".message" 1-            htmlAllContain ".message" "Some Content"-            htmlAllContain ".message" "text/plain"+import TestImport -        -- This is a simple example of using a database access in a test.  The-        -- test will succeed for a fresh scaffolded site with an empty database,-        -- but will fail on an existing database with a non-empty user table.-        yit "leaves the user table empty" $ do-            get HomeR-            statusIs 200-            users <- runDB $ selectList ([] :: [Filter User]) []-            assertEqual "user table empty" 0 $ L.length users+spec :: Spec+spec = withApp $ do+    it "loads the index and checks it looks right" $ do+        get HomeR+        statusIs 200+        htmlAllContain "h1" "Welcome to Yesod" -{-# START_FILE test/Spec.hs #-}-module Main where+        request $ do+            setMethod "POST"+            setUrl HomeR+            addNonce+            fileByLabel "Choose a file" "test/Spec.hs" "text/plain" -- talk about self-reference+            byLabel "What's on the file?" "Some Content" -import Import-import Yesod.Default.Config-import Yesod.Test-import Test.Hspec (hspec)-import Application (makeFoundation)+        statusIs 200+        -- more debugging printBody+        htmlCount ".message" 1+        htmlAllContain ".message" "Some Content"+        htmlAllContain ".message" "text/plain" -import qualified Handler.HomeSpec+    -- This is a simple example of using a database access in a test.  The+    -- test will succeed for a fresh scaffolded site with an empty database,+    -- but will fail on an existing database with a non-empty user table.+    it "leaves the user table empty" $ do+        get HomeR+        statusIs 200+        users <- runDB $ selectList ([] :: [Filter User]) []+        assertEqual "user table empty" 0 $ length users -main :: IO ()-main = do-    conf <- Yesod.Default.Config.loadConfig $ (configSettings Testing)-                { csParseExtra = parseExtra-                }-    foundation <- makeFoundation conf-    hspec $ do-        yesodSpec foundation $ do-            Handler.HomeSpec.spec+{-# START_FILE test/Spec.hs #-}+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}  {-# START_FILE test/TestImport.hs #-} module TestImport-    ( module Yesod.Test-    , module Model-    , module Foundation-    , module Database.Persist-    , module Prelude-    , runDB-    , Spec-    , Example+    ( module TestImport+    , module X     ) where -import Yesod.Test-import Database.Persist hiding (get)+import Application              (makeFoundation)+import ClassyPrelude            as X+import Database.Persist         as X hiding (get) import Database.Persist.MongoDB hiding (master)-import Control.Monad.Trans.Resource (ResourceT, runResourceT)-import Control.Monad.Logger (NoLoggingT, runNoLoggingT)-import Control.Monad.IO.Class (liftIO)-import Prelude--import Foundation-import Model+import Foundation               as X+import Model                    as X+import Settings                 (appDatabaseConf)+import Test.Hspec               as X+import Yesod.Default.Config2    (ignoreEnv, loadAppSettings)+import Yesod.Test               as X -type Spec = YesodSpec App-type Example = YesodExample App+runDB :: Action IO a -> YesodExample App a+runDB action = do+    master <- getTestYesod+    liftIO $ runMongoDBPool+        (mgAccessMode $ appDatabaseConf $ appSettings master)+        action+        (appConnPool master) -runDB :: Action (NoLoggingT (ResourceT IO)) a -> YesodExample App a-runDB query = do-    pool <- fmap connPool getTestYesod-    liftIO $ runResourceT $ runNoLoggingT $ runMongoDBPoolDef query pool+withApp :: SpecWith App -> Spec+withApp = before $ do+    settings <- loadAppSettings+        ["config/test-settings.yml", "config/settings.yml"]+        []+        ignoreEnv+    makeFoundation settings 
hsfiles/mysql.hsfiles view
@@ -28,32 +28,31 @@ {-# START_FILE Application.hs #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Application-    ( makeApplication-    , getApplicationDev+    ( getApplicationDev+    , appMain+    , develMain     , makeFoundation     ) where +import Control.Monad.Logger                 (liftLoc, runLoggingT)+import Database.Persist.MySQL               (createMySQLPool, myConnInfo,+                                             myPoolSize, runSqlPool) import Import-import Yesod.Auth-import Yesod.Default.Config-import Yesod.Default.Main-import Yesod.Default.Handlers-import Network.Wai.Middleware.RequestLogger-    ( mkRequestLogger, outputFormat, OutputFormat (..), IPAddrSource (..), destination-    )-import qualified Network.Wai.Middleware.RequestLogger as RequestLogger-import qualified Database.Persist-import Database.Persist.Sql (runMigration)-import Database.Persist.MySQL (createMySQLPool, myConnInfo, myPoolSize)-import Network.HTTP.Client.Conduit (newManager)-import Control.Monad.Logger (runLoggingT)-import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize)-import Network.Wai.Logger (clockDateCacher)-import Data.Default (def)-import Yesod.Core.Types (loggerSet, Logger (Logger))+import Language.Haskell.TH.Syntax           (qLocation)+import Network.Wai.Handler.Warp             (Settings, defaultSettings,+                                             defaultShouldDisplayException,+                                             runSettings, setHost,+                                             setOnException, setPort)+import Network.Wai.Middleware.RequestLogger (Destination (Logger),+                                             IPAddrSource (..),+                                             OutputFormat (..), destination,+                                             mkRequestLogger, outputFormat)+import System.Log.FastLogger                (defaultBufSize, newStdoutLoggerSet,+                                             toLogStr)  -- Import all relevant handler modules here. -- Don't forget to add new modules to your cabal file!+import Handler.Common import Handler.Home  -- This line actually creates our YesodDispatch instance. It is the second half@@ -61,112 +60,136 @@ -- 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+-- | This function allocates resources (such as a database connection pool),+-- performs initialization and return a foundation datatype value. This is also+-- the place to put your migrate statements to have automatic database -- migrations handled by Yesod.-makeApplication :: AppConfig DefaultEnv Extra -> IO (Application, LogFunc)-makeApplication conf = do-    foundation <- makeFoundation conf+makeFoundation :: AppSettings -> IO App+makeFoundation appSettings = do+    -- Some basic initializations: HTTP connection manager, logger, and static+    -- subsite.+    appHttpManager <- newManager+    appLogger <- newStdoutLoggerSet defaultBufSize >>= makeYesodLogger+    appStatic <-+        (if appMutableStatic appSettings then staticDevel else static)+        (appStaticDir appSettings) -    -- Initialize the logging middleware+    -- We need a log function to create a connection pool. We need a connection+    -- pool to create our foundation. And we need our foundation to get a+    -- logging function. To get out of this loop, we initially create a+    -- temporary foundation without a real connection pool, get a log function+    -- from there, and then create the real foundation.+    let mkFoundation appConnPool = App {..}+        tempFoundation = mkFoundation $ error "connPool forced in tempFoundation"+        logFunc = messageLoggerSource tempFoundation appLogger++    -- Create the database connection pool+    pool <- flip runLoggingT logFunc $ createMySQLPool+        (myConnInfo $ appDatabaseConf appSettings)+        (myPoolSize $ appDatabaseConf appSettings)++    -- Perform database migration using our application's logging settings.+    runLoggingT (runSqlPool (runMigration migrateAll) pool) logFunc++    -- Return the foundation+    return $ mkFoundation pool++-- | Convert our foundation to a WAI Application by calling @toWaiAppPlain@ and+-- applyng some additional middlewares.+makeApplication :: App -> IO Application+makeApplication foundation = do     logWare <- mkRequestLogger def         { outputFormat =-            if development+            if appDetailedRequestLogging $ appSettings foundation                 then Detailed True-                else Apache FromSocket-        , destination = RequestLogger.Logger $ loggerSet $ appLogger foundation+                else Apache+                        (if appIpFromHeader $ appSettings foundation+                            then FromFallback+                            else FromSocket)+        , destination = Logger $ loggerSet $ appLogger foundation         }      -- Create the WAI application and apply middlewares-    app <- toWaiAppPlain foundation-    let logFunc = messageLoggerSource foundation (appLogger foundation)-    return (logWare $ defaultMiddlewaresNoLogging app, logFunc)+    appPlain <- toWaiAppPlain foundation+    return $ logWare $ defaultMiddlewaresNoLogging appPlain --- | Loads up any necessary settings, creates your foundation datatype, and--- performs some initialization.-makeFoundation :: AppConfig DefaultEnv Extra -> IO App-makeFoundation conf = do-    manager <- newManager-    s <- staticSite-    dbconf <- withYamlEnvironment "config/mysql.yml" (appEnv conf)-              Database.Persist.loadConfig >>=-              Database.Persist.applyEnv+-- | Warp settings for the given foundation value.+warpSettings :: App -> Settings+warpSettings foundation =+      setPort (appPort $ appSettings foundation)+    $ setHost (appHost $ appSettings foundation)+    $ setOnException (\_req e ->+        when (defaultShouldDisplayException e) $ messageLoggerSource+            foundation+            (appLogger foundation)+            $(qLocation >>= liftLoc)+            "yesod"+            LevelError+            (toLogStr $ "Exception from Warp: " ++ show e))+      defaultSettings -    loggerSet' <- newStdoutLoggerSet defaultBufSize-    (getter, _) <- clockDateCacher+-- | For yesod devel, return the Warp settings and WAI Application.+getApplicationDev :: IO (Settings, Application)+getApplicationDev = do+    settings <- loadAppSettings [configSettingsYml] [] useEnv+    foundation <- makeFoundation settings+    app <- makeApplication foundation+    wsettings <- getDevSettings $ warpSettings foundation+    return (wsettings, app) -    let logger = Yesod.Core.Types.Logger loggerSet' getter-        mkFoundation p = App-            { settings = conf-            , getStatic = s-            , connPool = p-            , httpManager = manager-            , persistConfig = dbconf-            , appLogger = logger-            }-        tempFoundation = mkFoundation $ error "connPool forced in tempFoundation"-        logFunc = messageLoggerSource tempFoundation logger+-- | main function for use by yesod devel+develMain :: IO ()+develMain = develMainHelper getApplicationDev -    p <- flip runLoggingT logFunc-       $ createMySQLPool (myConnInfo dbconf) (myPoolSize dbconf)-    let foundation = mkFoundation p+-- | The @main@ function for an executable running this site.+appMain :: IO ()+appMain = do+    -- Get the settings from all relevant sources+    settings <- loadAppSettingsArgs+        -- fall back to compile-time values, set to [] to require values at runtime+        [configSettingsYmlValue] -    -- Perform database migration using our application's logging settings.-    flip runLoggingT logFunc-        (Database.Persist.runPool dbconf (runMigration migrateAll) p)+        -- allow environment variables to override+        useEnv -    return foundation+    -- Generate the foundation from the settings+    foundation <- makeFoundation settings --- for yesod devel-getApplicationDev :: IO (Int, Application)-getApplicationDev =-    defaultDevelApp loader (fmap fst . makeApplication)-  where-    loader = Yesod.Default.Config.loadConfig (configSettings Development)-        { csParseExtra = parseExtra-        }+    -- Generate a WAI Application from the foundation+    app <- makeApplication foundation +    -- Run the application with Warp+    runSettings (warpSettings foundation) app+ {-# START_FILE Foundation.hs #-} module Foundation where -import Prelude-import Yesod-import Yesod.Static-import Yesod.Auth-import Yesod.Auth.BrowserId-import Yesod.Default.Config-import Yesod.Default.Util (addStaticContentExternal)-import Network.HTTP.Client.Conduit (Manager, HasHttpManager (getHttpManager))-import qualified Settings-import Settings.Development (development)-import qualified Database.Persist-import Database.Persist.Sql (SqlBackend)-import Settings.StaticFiles-import Settings (widgetFile, Extra (..))+import ClassyPrelude.Yesod+import Database.Persist.Sql (ConnectionPool, runSqlPool) import Model-import Text.Jasmine (minifym)-import Text.Hamlet (hamletFile)-import Yesod.Core.Types (Logger)+import Settings+import Settings.StaticFiles+import Text.Hamlet          (hamletFile)+import Text.Jasmine         (minifym)+import Yesod.Auth+import Yesod.Auth.BrowserId (authBrowserId)+import Yesod.Core.Types     (Logger)+import Yesod.Default.Util   (addStaticContentExternal) --- | The site argument for your application. This can be a good place to+-- | The foundation datatype 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.-    , connPool :: Database.Persist.PersistConfigPool Settings.PersistConf -- ^ Database connection pool.-    , httpManager :: Manager-    , persistConfig :: Settings.PersistConf-    , appLogger :: Logger+    { appSettings    :: AppSettings+    , appStatic      :: Static -- ^ Settings for static file serving.+    , appConnPool    :: ConnectionPool -- ^ Database connection pool.+    , appHttpManager :: Manager+    , appLogger      :: Logger     }  instance HasHttpManager App where-    getHttpManager = httpManager---- Set up i18n messages. See the message folder.-mkMessage "App" "messages" "en"+    getHttpManager = appHttpManager  -- This is where we define all of the routes in our application. For a full -- explanation of the syntax, please see:@@ -177,12 +200,15 @@ -- explanation for this split. mkYesodData "App" $(parseRoutesFile "config/routes") +-- | A convenient synonym for creating forms. type Form x = Html -> MForm (HandlerT App IO) (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+    -- Controls the base of generated URLs. For more information on modifying,+    -- see: https://github.com/yesodweb/yesod/wiki/Overriding-approot+    approot = ApprootMaster $ appRoot . appSettings      -- Store session data on the client in encrypted cookies,     -- default session idle timeout is 120 minutes@@ -205,12 +231,6 @@             $(widgetFile "default-layout")         withUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet") -    -- This is done to provide an optimization for serving static files from-    -- a separate domain. Please see the staticRoot setting in Settings.hs-    urlRenderOverride y (StaticR s) =-        Just $ uncurry (joinPath y (Settings.staticRoot $ settings y)) $ renderRoute s-    urlRenderOverride _ _ = Nothing-     -- The page to be redirected to when authentication is required.     authRoute _ = Just $ AuthR LoginR @@ -225,30 +245,38 @@     -- and names them based on a hash of their content. This allows     -- expiration dates to be set far in the future without worry of     -- users receiving stale content.-    addStaticContent =-        addStaticContentExternal minifym genFileName Settings.staticDir (StaticR . flip StaticRoute [])+    addStaticContent ext mime content = do+        master <- getYesod+        let staticDir = appStaticDir $ appSettings master+        addStaticContentExternal+            minifym+            genFileName+            staticDir+            (StaticR . flip StaticRoute [])+            ext+            mime+            content       where         -- Generate a unique filename based on the content itself-        genFileName lbs-            | development = "autogen-" ++ base64md5 lbs-            | otherwise   = base64md5 lbs--    -- Place Javascript at bottom of the body tag so the rest of the page loads first-    jsLoader _ = BottomOfBody+        genFileName lbs = "autogen-" ++ base64md5 lbs      -- What messages should be logged. The following includes all messages when     -- in development, and warnings and errors in production.-    shouldLog _ _source level =-        development || level == LevelWarn || level == LevelError+    shouldLog app _source level =+        appShouldLogAll (appSettings app)+            || level == LevelWarn+            || level == LevelError      makeLogger = return . appLogger  -- How to run database actions. instance YesodPersist App where     type YesodPersistBackend App = SqlBackend-    runDB = defaultRunDB persistConfig connPool+    runDB action = do+        master <- getYesod+        runSqlPool action $ appConnPool master instance YesodPersistRunner App where-    getDBRunner = defaultGetDBRunner connPool+    getDBRunner = defaultGetDBRunner appConnPool  instance YesodAuth App where     type AuthId App = UserId@@ -257,6 +285,8 @@     loginDest _ = HomeR     -- Where to send a user after logout     logoutDest _ = HomeR+    -- Override the above two destinations when a Referer: header is present+    redirectToReferer _ = True      getAuthId creds = runDB $ do         x <- getBy $ UniqueUser $ credsIdent creds@@ -271,7 +301,7 @@     -- You can add other plugins like BrowserID, email or OAuth here     authPlugins _ = [authBrowserId def] -    authHttpManager = httpManager+    authHttpManager = getHttpManager  instance YesodAuthPersist App @@ -280,23 +310,38 @@ instance RenderMessage App FormMessage where     renderMessage _ _ = defaultFormMessage --- | Get the 'Extra' value, used to hold data from the settings.yml file.-getExtra :: Handler Extra-getExtra = fmap (appExtra . settings) getYesod---- Note: previous versions of the scaffolding included a deliver function to--- send emails. Unfortunately, there are too many different options for us to--- give a reasonable default. Instead, the information is available on the--- wiki:+-- Note: Some functionality previously present in the scaffolding has been+-- moved to documentation in the Wiki. Following are some hopefully helpful+-- links: -- -- https://github.com/yesodweb/yesod/wiki/Sending-email+-- https://github.com/yesodweb/yesod/wiki/Serve-static-files-from-a-separate-domain+-- https://github.com/yesodweb/yesod/wiki/i18n-messages-in-the-scaffolding +{-# START_FILE Handler/Common.hs #-}+-- | Common handler functions.+module Handler.Common where++import Data.FileEmbed (embedFile)+import Import++-- These handlers embed files in the executable at compile time to avoid a+-- runtime dependency, and for efficiency.++getFaviconR :: Handler TypedContent+getFaviconR = return $ TypedContent "image/x-icon"+                     $ toContent $(embedFile "config/favicon.ico")++getRobotsR :: Handler TypedContent+getRobotsR = return $ TypedContent typePlain+                    $ toContent $(embedFile "config/robots.txt")+ {-# START_FILE Handler/Home.hs #-} module Handler.Home where  import Import-import Yesod.Form.Bootstrap3-    ( BootstrapFormLayout (..), renderBootstrap3, withSmallInput )+import Yesod.Form.Bootstrap3 (BootstrapFormLayout (..), renderBootstrap3,+                              withSmallInput)  -- This is a handler function for the GET request method on the HomeR -- resource pattern. All of your resource patterns are defined in@@ -338,40 +383,20 @@     ( module Import     ) where -import           Prelude              as Import hiding (head, init, last,-                                                 readFile, tail, writeFile)-import           Yesod                as Import hiding (Route (..))--import           Control.Applicative  as Import (pure, (<$>), (<*>))-import           Data.Text            as Import (Text)--import           Foundation           as Import-import           Model                as Import-import           Settings             as Import-import           Settings.Development as Import-import           Settings.StaticFiles as Import--#if __GLASGOW_HASKELL__ >= 704-import           Data.Monoid          as Import-                                                 (Monoid (mappend, mempty, mconcat),-                                                 (<>))-#else-import           Data.Monoid          as Import-                                                 (Monoid (mappend, mempty, mconcat))--infixr 5 <>-(<>) :: Monoid m => m -> m -> m-(<>) = mappend-#endif+import ClassyPrelude.Yesod   as Import+import Foundation            as Import+import Model                 as Import+import Settings              as Import+import Settings.StaticFiles  as Import+import Yesod.Auth            as Import+import Yesod.Core.Types      as Import (loggerSet)+import Yesod.Default.Config2 as Import  {-# START_FILE Model.hs #-} module Model where -import Yesod-import Data.Text (Text)+import ClassyPrelude.Yesod import Database.Persist.Quasi-import Data.Typeable (Typeable)-import Prelude  -- You can define all of your database entities in the entities file. -- You can find more information on persistent and how to declare entities@@ -401,7 +426,7 @@                      Model                      Settings                      Settings.StaticFiles-                     Settings.Development+                     Handler.Common                      Handler.Home      if flag(dev) || flag(library-only)@@ -425,17 +450,21 @@                 DeriveDataTypeable                 ViewPatterns                 TupleSections+                RecordWildCards      build-depends: base                          >= 4          && < 5-                 , yesod                         >= 1.4.0      && < 1.5+                 , yesod                         >= 1.4.1      && < 1.5                  , yesod-core                    >= 1.4.0      && < 1.5                  , yesod-auth                    >= 1.4.0      && < 1.5-                 , yesod-static                  >= 1.4.0      && < 1.5+                 , yesod-static                  >= 1.4.0.3    && < 1.5                  , yesod-form                    >= 1.4.0      && < 1.5+                 , classy-prelude                >= 0.10.2+                 , classy-prelude-conduit        >= 0.10.2+                 , classy-prelude-yesod          >= 0.10.2                  , bytestring                    >= 0.9        && < 0.11                  , text                          >= 0.11       && < 2.0                  , persistent                    >= 2.0        && < 2.2-                 , persistent-mysql              >= 2.0        && < 2.2+                 , persistent-mysql              >= 2.1.2      && < 2.2                  , persistent-template           >= 2.0        && < 2.2                  , template-haskell                  , shakespeare                   >= 2.0        && < 2.1@@ -452,10 +481,12 @@                  , monad-logger                  >= 0.3        && < 0.4                  , fast-logger                   >= 2.2        && < 2.3                  , wai-logger                    >= 2.2        && < 2.3--    -- see https://github.com/yesodweb/yesod/issues/814-    if !os(windows)-        build-depends: unix+                 , file-embed+                 , safe+                 , unordered-containers+                 , containers+                 , vector+                 , time  executable         PROJECTNAME     if flag(library-only)@@ -463,9 +494,7 @@      main-is:           main.hs     hs-source-dirs:    app-    build-depends:     base-                     , PROJECTNAME-                     , yesod+    build-depends:     base, PROJECTNAME      ghc-options:       -threaded -O2 -rtsopts -with-rtsopts=-N @@ -493,7 +522,7 @@      build-depends: base                  , PROJECTNAME-                 , yesod-test >= 1.4 && < 1.5+                 , yesod-test >= 1.4.2 && < 1.5                  , yesod-core                  , yesod                  , persistent@@ -502,6 +531,8 @@                  , monad-logger                  , transformers                  , hspec+                 , classy-prelude+                 , classy-prelude-yesod  {-# START_FILE Settings.hs #-} -- | Settings are centralized, as much as possible, into this file. This@@ -511,45 +542,81 @@ -- declared in the Foundation.hs file. module Settings where -import Prelude-import Text.Shakespeare.Text (st)-import Language.Haskell.TH.Syntax-import Database.Persist.MySQL (MySQLConf)-import Yesod.Default.Config-import Yesod.Default.Util-import Data.Text (Text)-import Data.Yaml-import Control.Applicative-import Settings.Development-import Data.Default (def)-import Text.Hamlet+import ClassyPrelude.Yesod+import Control.Exception          (throw)+import Data.Aeson                 (Result (..), fromJSON, withObject, (.!=),+                                   (.:?))+import Data.FileEmbed             (embedFile)+import Data.Yaml                  (decodeEither')+import Database.Persist.MySQL     (MySQLConf)+import Language.Haskell.TH.Syntax (Exp, Name, Q)+import Network.Wai.Handler.Warp   (HostPreference)+import Yesod.Default.Config2      (applyEnvValue, configSettingsYml)+import Yesod.Default.Util         (WidgetFileSettings, widgetFileNoReload,+                                   widgetFileReload) --- | Which Persistent backend this site is using.-type PersistConf = MySQLConf+-- | Runtime settings to configure this application. These settings can be+-- loaded from various sources: defaults, environment variables, config files,+-- theoretically even a database.+data AppSettings = AppSettings+    { appStaticDir              :: String+    -- ^ Directory from which to serve static files.+    , appDatabaseConf           :: MySQLConf+    -- ^ Configuration settings for accessing the database.+    , appRoot                   :: Text+    -- ^ Base for all generated URLs.+    , appHost                   :: HostPreference+    -- ^ Host/interface the server should bind to.+    , appPort                   :: Int+    -- ^ Port to listen on+    , appIpFromHeader           :: Bool+    -- ^ Get the IP address from the header when logging. Useful when sitting+    -- behind a reverse proxy. --- Static setting below. Changing these requires a recompile+    , appDetailedRequestLogging :: Bool+    -- ^ Use detailed request logging system+    , appShouldLogAll           :: Bool+    -- ^ Should all log messages be displayed?+    , appReloadTemplates        :: Bool+    -- ^ Use the reload version of templates+    , appMutableStatic          :: Bool+    -- ^ Assume that files in the static dir may change after compilation+    , appSkipCombining          :: Bool+    -- ^ Perform no stylesheet/script combining --- | The location of static files on your system. This is a file system--- path. The default value works properly with your scaffolded site.-staticDir :: FilePath-staticDir = "static"+    -- Example app-specific configuration values.+    , appCopyright              :: Text+    -- ^ Copyright text to appear in the footer of the page+    , appAnalytics              :: Maybe Text+    -- ^ Google Analytics code+    } --- | The base URL for your static files. As you can see by the default--- value, this can simply be "static" appended to your application root.--- A powerful optimization can be serving static files from a separate--- domain name. This allows you to use a web server optimized for static--- files, more easily set expires and cache values, and avoid possibly--- costly transference of cookies on static files. For more information,--- please see:---   http://code.google.com/speed/page-speed/docs/request.html#ServeFromCookielessDomain------ If you change the resource pattern for StaticR in Foundation.hs, you will--- have to make a corresponding change here.------ To see how this value is used, see urlRenderOverride in Foundation.hs-staticRoot :: AppConfig DefaultEnv x -> Text-staticRoot conf = [st|#{appRoot conf}/static|]+instance FromJSON AppSettings where+    parseJSON = withObject "AppSettings" $ \o -> do+        let defaultDev =+#if DEVELOPMENT+                True+#else+                False+#endif+        appStaticDir              <- o .: "static-dir"+        appDatabaseConf           <- o .: "database"+        appRoot                   <- o .: "approot"+        appHost                   <- fromString <$> o .: "host"+        appPort                   <- o .: "port"+        appIpFromHeader           <- o .: "ip-from-header" +        appDetailedRequestLogging <- o .:? "detailed-logging" .!= defaultDev+        appShouldLogAll           <- o .:? "should-log-all"   .!= defaultDev+        appReloadTemplates        <- o .:? "reload-templates" .!= defaultDev+        appMutableStatic          <- o .:? "mutable-static"   .!= defaultDev+        appSkipCombining          <- o .:? "skip-combining"   .!= defaultDev++        appCopyright              <- o .: "copyright"+        appAnalytics              <- o .:? "analytics"++        return AppSettings {..}+ -- | Settings for 'widgetFile', such as which template languages to support and -- default Hamlet settings. --@@ -558,81 +625,62 @@ -- https://github.com/yesodweb/yesod/wiki/Overriding-widgetFile widgetFileSettings :: WidgetFileSettings widgetFileSettings = def-    { wfsHamletSettings = defaultHamletSettings-        { hamletNewlines = AlwaysNewlines-        }-    } +-- | How static files should be combined.+combineSettings :: CombineSettings+combineSettings = def+ -- The rest of this file contains settings which rarely need changing by a -- user.  widgetFile :: String -> Q Exp-widgetFile = (if development then widgetFileReload-                             else widgetFileNoReload)+widgetFile = (if appReloadTemplates compileTimeAppSettings+                then widgetFileReload+                else widgetFileNoReload)               widgetFileSettings -data Extra = Extra-    { extraCopyright :: Text-    , extraAnalytics :: Maybe Text -- ^ Google Analytics-    } deriving Show+-- | Raw bytes at compile time of @config/settings.yml@+configSettingsYmlBS :: ByteString+configSettingsYmlBS = $(embedFile configSettingsYml) -parseExtra :: DefaultEnv -> Object -> Parser Extra-parseExtra _ o = Extra-    <$> o .:  "copyright"-    <*> o .:? "analytics"+-- | @config/settings.yml@, parsed to a @Value@.+configSettingsYmlValue :: Value+configSettingsYmlValue = either throw id $ decodeEither' configSettingsYmlBS -{-# START_FILE Settings/Development.hs #-}-module Settings.Development where+-- | A version of @AppSettings@ parsed at compile time from @config/settings.yml@.+compileTimeAppSettings :: AppSettings+compileTimeAppSettings =+    case fromJSON $ applyEnvValue False mempty configSettingsYmlValue of+        Error e -> error e+        Success settings -> settings -import Prelude+-- The following two functions can be used to combine multiple CSS or JS files+-- at compile time to decrease the number of http requests.+-- Sample usage (inside a Widget):+--+-- > $(combineStylesheets 'StaticR [style1_css, style2_css]) -development :: Bool-development =-#if DEVELOPMENT-  True-#else-  False-#endif+combineStylesheets :: Name -> [Route Static] -> Q Exp+combineStylesheets = combineStylesheets'+    (appSkipCombining compileTimeAppSettings)+    combineSettings -production :: Bool-production = not development+combineScripts :: Name -> [Route Static] -> Q Exp+combineScripts = combineScripts'+    (appSkipCombining compileTimeAppSettings)+    combineSettings  {-# START_FILE Settings/StaticFiles.hs #-} module Settings.StaticFiles where -import Prelude (IO)-import Yesod.Static-import qualified Yesod.Static as Static-import Settings (staticDir)-import Settings.Development-import Language.Haskell.TH (Q, Exp, Name)-import Data.Default (def)---- | use this to create your static file serving site-staticSite :: IO Static.Static-staticSite = if development then Static.staticDevel staticDir-                            else Static.static      staticDir+import Settings     (appStaticDir, compileTimeAppSettings)+import Yesod.Static (staticFiles)  -- | This generates easy references to files in the static directory at compile time, --   giving you compile-time verification that referenced files exist. --   Warning: any files added to your static directory during run-time can't be --   accessed this way. You'll have to use their FilePath or URL to access them.-$(staticFiles Settings.staticDir)--combineSettings :: CombineSettings-combineSettings = def---- The following two functions can be used to combine multiple CSS or JS files--- at compile time to decrease the number of http requests.--- Sample usage (inside a Widget):------ > $(combineStylesheets 'StaticR [style1_css, style2_css])--combineStylesheets :: Name -> [Route Static] -> Q Exp-combineStylesheets = combineStylesheets' development combineSettings--combineScripts :: Name -> [Route Static] -> Q Exp-combineScripts = combineScripts' development combineSettings+staticFiles (appStaticDir compileTimeAppSettings)  {-# START_FILE app/DevelMain.hs #-} -- | Development version to be run inside GHCi.@@ -699,19 +747,24 @@ start :: MVar () -- ^ Written to when the thread is killed.       -> IO ThreadId start done = do-    (port,app) <- getApplicationDev-    forkIO (finally (runSettings (setPort port defaultSettings) app)+    (settings,app) <- getApplicationDev+    forkIO (finally (runSettings settings app)                     (putMVar done ())) +{-# START_FILE app/devel.hs #-}+{-# LANGUAGE PackageImports #-}+import "PROJECTNAME" Application (develMain)+import Prelude (IO)++main :: IO ()+main = develMain+ {-# START_FILE app/main.hs #-}-import Prelude              (IO)-import Yesod.Default.Config (fromArgs)-import Yesod.Default.Main   (defaultMainLog)-import Settings             (parseExtra)-import Application          (makeApplication)+import Prelude     (IO)+import Application (appMain)  main :: IO ()-main = defaultMainLog (fromArgs parseExtra) makeApplication+main = appMain  {-# START_FILE BASE64 config/favicon.ico #-} AAABAAIAEBAAAAEAIABoBAAAJgAAABAQAgABAAEAsAAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAA@@ -816,46 +869,11 @@   -- By default this file is used in Model.hs (which is imported by Foundation.hs) -{-# START_FILE config/mysql.yml #-}-# NOTE: These settings can be overridden by environment variables as well, in-# particular:-#-#    MYSQL_HOST-#    MYSQL_PORT-#    MYSQL_USER-#    MYSQL_PASSWORD-#    MYSQL_DATABASE--Default: &defaults-  user: PROJECTNAME-  password: PROJECTNAME-  host: localhost-  port: 3306-  database: PROJECTNAME-  poolsize: 10--Development:-  <<: *defaults--Testing:-  database: PROJECTNAME_test-  <<: *defaults--Staging:-  database: PROJECTNAME_staging-  poolsize: 100-  <<: *defaults--Production:-  database: PROJECTNAME_production-  poolsize: 100-  <<: *defaults- {-# START_FILE config/robots.txt #-} User-agent: *  {-# START_FILE config/routes #-}-/static StaticR Static getStatic+/static StaticR Static appStatic /auth   AuthR   Auth   getAuth  /favicon.ico FaviconR GET@@ -864,155 +882,36 @@ / HomeR GET POST  {-# START_FILE config/settings.yml #-}-Default: &defaults-  host: "*4" # any IPv4 host-  port: 3000-  approot: "http://localhost:3000"-  copyright: Insert copyright statement here-  #analytics: UA-YOURCODE--Development:-  <<: *defaults--Testing:-  <<: *defaults--Staging:-  <<: *defaults--Production:-  #approot: "http://www.example.com"-  <<: *defaults--{-# START_FILE deploy/Procfile #-}-# Free deployment to Heroku.-#-#   !! Warning: You must use a 64 bit machine to compile !!-#-#   This could mean using a virtual machine. Give your VM as much memory as you can to speed up linking.-#-# Basic Yesod setup:-#-# * Move this file out of the deploy directory and into your root directory-#-#     mv deploy/Procfile ./-#-# * Create an empty package.json-#     echo '{ "name": "PROJECTNAME", "version": "0.0.1", "dependencies": {} }' >> package.json-#-# Postgresql Yesod setup:-#-# * add dependencies on the "heroku", "aeson" and "unordered-containers" packages in your cabal file-#-# * add code in Application.hs to use the heroku package and load the connection parameters.-#   The below works for Postgresql.-#-#   import Data.HashMap.Strict as H-#   import Data.Aeson.Types as AT-#   #ifndef DEVELOPMENT-#   import qualified Web.Heroku-#   #endif-#-#-#-#   makeFoundation :: AppConfig DefaultEnv Extra -> Logger -> IO App-#   makeFoundation conf setLogger = do-#       manager <- newManager def-#       s <- staticSite-#       hconfig <- loadHerokuConfig-#       dbconf <- withYamlEnvironment "config/postgresql.yml" (appEnv conf)-#                 (Database.Persist.Store.loadConfig . combineMappings hconfig) >>=-#                 Database.Persist.Store.applyEnv-#       p <- Database.Persist.Store.createPoolConfig (dbconf :: Settings.PersistConfig)-#       Database.Persist.Store.runPool dbconf (runMigration migrateAll) p-#       return $ App conf setLogger s p manager dbconf-#-#   #ifndef DEVELOPMENT-#   canonicalizeKey :: (Text, val) -> (Text, val)-#   canonicalizeKey ("dbname", val) = ("database", val)-#   canonicalizeKey pair = pair-#-#   toMapping :: [(Text, Text)] -> AT.Value-#   toMapping xs = AT.Object $ M.fromList $ map (\(key, val) -> (key, AT.String val)) xs-#   #endif-#-#   combineMappings :: AT.Value -> AT.Value -> AT.Value-#   combineMappings (AT.Object m1) (AT.Object m2) = AT.Object $ m1 `M.union` m2-#   combineMappings _ _ = error "Data.Object is not a Mapping."-#-#   loadHerokuConfig :: IO AT.Value-#   loadHerokuConfig = do-#   #ifdef DEVELOPMENT-#       return $ AT.Object M.empty-#   #else-#       Web.Heroku.dbConnParams >>= return . toMapping . map canonicalizeKey-#   #endif--+static-dir:     "_env:STATIC_DIR:static"+host:           "_env:HOST:*4" # any IPv4 host+port:           "_env:PORT:3000"+approot:        "_env:APPROOT:http://localhost:3000"+ip-from-header: "_env:IP_FROM_HEADER:false" -# Heroku setup:-# Find the Heroku guide. Roughly:-#-# * sign up for a heroku account and register your ssh key-# * create a new application on the *cedar* stack-#-# * make your Yesod project the git repository for that application-# * create a deploy branch-#-#     git checkout -b deploy-#-# Repeat these steps to deploy:-# * add your web executable binary (referenced below) to the git repository-#-#     git checkout deploy-#     git add ./dist/build/PROJECTNAME/PROJECTNAME-#     git commit -m deploy-#-# * push to Heroku+# Optional values with the following production defaults.+# In development, they default to the inverse. #-#     git push heroku deploy:master---# Heroku configuration that runs your app-web: ./dist/build/PROJECTNAME/PROJECTNAME production -p $PORT--{-# START_FILE devel.hs #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE PackageImports #-}-import "PROJECTNAME" Application (getApplicationDev)-import Network.Wai.Handler.Warp-    (runSettings, defaultSettings, setPort)-import Control.Concurrent (forkIO)-import System.Directory (doesFileExist, removeFile)-import System.Exit (exitSuccess)-import Control.Concurrent (threadDelay)--#ifndef mingw32_HOST_OS-import System.Posix.Signals (installHandler, sigINT, Handler(Catch))-#endif--main :: IO ()-main = do-#ifndef mingw32_HOST_OS-    _ <- installHandler sigINT (Catch $ return ()) Nothing-#endif--    putStrLn "Starting devel application"-    (port, app) <- getApplicationDev-    forkIO $ runSettings (setPort port defaultSettings) app-    loop+# development: false+# detailed-logging: false+# should-log-all: false+# reload-templates: false+# mutable-static: false+# skip-combining: false -loop :: IO ()-loop = do-  threadDelay 100000-  e <- doesFileExist "yesod-devel/devel-terminate"-  if e then terminateDevel else loop+database:+  user:     "_env:MYSQL_USER:PROJECTNAME"+  password: "_env:MYSQL_PASSWORD:PROJECTNAME"+  host:     "_env:MYSQL_HOST:localhost"+  port:     "_env:MYSQL_PORT:5432"+  database: "_env:MYSQL_DATABASE:PROJECTNAME"+  poolsize: "_env:MYSQL_POOLSIZE:10" -terminateDevel :: IO ()-terminateDevel = exitSuccess+copyright: Insert copyright statement here+#analytics: UA-YOURCODE -{-# START_FILE messages/en.msg #-}-Hello: Hello+{-# START_FILE config/test-settings.yml #-}+database:+  database: PROJECTNAME_test  {-# START_FILE static/css/bootstrap.css #-} /*!@@ -8978,9 +8877,9 @@             <div id="main" role="main">               ^{pageBody pc}             <footer>-                #{extraCopyright $ appExtra $ settings master}+                #{appCopyright $ appSettings master} -        $maybe analytics <- extraAnalytics $ appExtra $ settings master+        $maybe analytics <- appAnalytics $ appSettings master             <script>               if(!window.location.href.match(/localhost/)){                 window._gaq = [['_setAccount','#{analytics}'],['_trackPageview'],['_trackPageLoadTime']];@@ -9003,7 +8902,7 @@ ^{widget}  {-# START_FILE templates/homepage.hamlet #-}-<h1>_{MsgHello}+<h1>Welcome to Yesod!  <ol>   <li>Now that you have a working project you should use the #@@ -9054,92 +8953,88 @@     color: #990 } -{-# START_FILE test/Handler/HomeSpec.hs #-}-module Handler.HomeSpec-    ( spec-    ) where+{-# START_FILE test/Handler/CommonSpec.hs #-}+module Handler.CommonSpec (spec) where  import TestImport-import qualified Data.List as L  spec :: Spec-spec =-    ydescribe "These are some example tests" $ do--        yit "loads the index and checks it looks right" $ do-            get HomeR+spec = withApp $ do+    describe "robots.txt" $ do+        it "gives a 200" $ do+            get RobotsR             statusIs 200-            htmlAllContain "h1" "Hello"+        it "has correct User-agent" $ do+            get RobotsR+            bodyContains "User-agent: *"+    describe "favicon.ico" $ do+        it "gives a 200" $ do+            get FaviconR+            statusIs 200 -            request $ do-                setMethod "POST"-                setUrl HomeR-                addNonce-                fileByLabel "Choose a file" "test/Spec.hs" "text/plain" -- talk about self-reference-                byLabel "What's on the file?" "Some Content"+{-# START_FILE test/Handler/HomeSpec.hs #-}+module Handler.HomeSpec (spec) where -            statusIs 200-            -- more debugging printBody-            htmlCount ".message" 1-            htmlAllContain ".message" "Some Content"-            htmlAllContain ".message" "text/plain"+import TestImport -        -- This is a simple example of using a database access in a test.  The-        -- test will succeed for a fresh scaffolded site with an empty database,-        -- but will fail on an existing database with a non-empty user table.-        yit "leaves the user table empty" $ do-            get HomeR-            statusIs 200-            users <- runDB $ selectList ([] :: [Filter User]) []-            assertEqual "user table empty" 0 $ L.length users+spec :: Spec+spec = withApp $ do+    it "loads the index and checks it looks right" $ do+        get HomeR+        statusIs 200+        htmlAllContain "h1" "Welcome to Yesod" -{-# START_FILE test/Spec.hs #-}-module Main where+        request $ do+            setMethod "POST"+            setUrl HomeR+            addNonce+            fileByLabel "Choose a file" "test/Spec.hs" "text/plain" -- talk about self-reference+            byLabel "What's on the file?" "Some Content" -import Import-import Yesod.Default.Config-import Yesod.Test-import Test.Hspec (hspec)-import Application (makeFoundation)+        statusIs 200+        -- more debugging printBody+        htmlCount ".message" 1+        htmlAllContain ".message" "Some Content"+        htmlAllContain ".message" "text/plain" -import qualified Handler.HomeSpec+    -- This is a simple example of using a database access in a test.  The+    -- test will succeed for a fresh scaffolded site with an empty database,+    -- but will fail on an existing database with a non-empty user table.+    it "leaves the user table empty" $ do+        get HomeR+        statusIs 200+        users <- runDB $ selectList ([] :: [Filter User]) []+        assertEqual "user table empty" 0 $ length users -main :: IO ()-main = do-    conf <- Yesod.Default.Config.loadConfig $ (configSettings Testing)-                { csParseExtra = parseExtra-                }-    foundation <- makeFoundation conf-    hspec $ do-        yesodSpec foundation $ do-            Handler.HomeSpec.spec+{-# START_FILE test/Spec.hs #-}+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}  {-# START_FILE test/TestImport.hs #-} module TestImport-    ( module Yesod.Test-    , module Model-    , module Foundation-    , module Database.Persist-    , module Prelude-    , runDB-    , Spec-    , Example+    ( module TestImport+    , module X     ) where -import Yesod.Test-import Database.Persist hiding (get)-import Database.Persist.Sql (SqlPersistM, runSqlPersistMPool)-import Control.Monad.IO.Class (liftIO)-import Prelude--import Foundation-import Model--type Spec = YesodSpec App-type Example = YesodExample App+import Application           (makeFoundation)+import ClassyPrelude         as X+import Database.Persist      as X hiding (get)+import Database.Persist.Sql  (SqlPersistM, runSqlPersistMPool)+import Foundation            as X+import Model                 as X+import Test.Hspec            as X+import Yesod.Default.Config2 (ignoreEnv, loadAppSettings)+import Yesod.Test            as X -runDB :: SqlPersistM a -> Example a+runDB :: SqlPersistM a -> YesodExample App a runDB query = do-    pool <- fmap connPool getTestYesod+    pool <- fmap appConnPool getTestYesod     liftIO $ runSqlPersistMPool query pool++withApp :: SpecWith App -> Spec+withApp = before $ do+    settings <- loadAppSettings+        ["config/test-settings.yml", "config/settings.yml"]+        []+        ignoreEnv+    makeFoundation settings 
hsfiles/postgres-fay.hsfiles view
@@ -31,33 +31,32 @@ {-# START_FILE Application.hs #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Application-    ( makeApplication-    , getApplicationDev+    ( getApplicationDev+    , appMain+    , develMain     , makeFoundation     ) where +import Control.Monad.Logger                 (liftLoc, runLoggingT)+import Database.Persist.Postgresql          (createPostgresqlPool, pgConnStr,+                                             pgPoolSize, runSqlPool) import Import-import Yesod.Auth-import Yesod.Default.Config-import Yesod.Default.Main-import Yesod.Default.Handlers-import Network.Wai.Middleware.RequestLogger-    ( mkRequestLogger, outputFormat, OutputFormat (..), IPAddrSource (..), destination-    )-import qualified Network.Wai.Middleware.RequestLogger as RequestLogger-import qualified Database.Persist-import Database.Persist.Sql (runMigration)-import Database.Persist.Postgresql (createPostgresqlPool, pgConnStr, pgPoolSize)-import Network.HTTP.Client.Conduit (newManager)-import Yesod.Fay (getFaySite)-import Control.Monad.Logger (runLoggingT)-import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize)-import Network.Wai.Logger (clockDateCacher)-import Data.Default (def)-import Yesod.Core.Types (loggerSet, Logger (Logger))+import Language.Haskell.TH.Syntax           (qLocation)+import Network.Wai.Handler.Warp             (Settings, defaultSettings,+                                             defaultShouldDisplayException,+                                             runSettings, setHost,+                                             setOnException, setPort)+import Network.Wai.Middleware.RequestLogger (Destination (Logger),+                                             IPAddrSource (..),+                                             OutputFormat (..), destination,+                                             mkRequestLogger, outputFormat)+import System.Log.FastLogger                (defaultBufSize, newStdoutLoggerSet,+                                             toLogStr)+import Yesod.Fay                            (getFaySite)  -- Import all relevant handler modules here. -- Don't forget to add new modules to your cabal file!+import Handler.Common import Handler.Fay import Handler.Home @@ -66,114 +65,138 @@ -- 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+-- | This function allocates resources (such as a database connection pool),+-- performs initialization and return a foundation datatype value. This is also+-- the place to put your migrate statements to have automatic database -- migrations handled by Yesod.-makeApplication :: AppConfig DefaultEnv Extra -> IO (Application, LogFunc)-makeApplication conf = do-    foundation <- makeFoundation conf+makeFoundation :: AppSettings -> IO App+makeFoundation appSettings = do+    -- Some basic initializations: HTTP connection manager, logger, and static+    -- subsite.+    appHttpManager <- newManager+    appLogger <- newStdoutLoggerSet defaultBufSize >>= makeYesodLogger+    appStatic <-+        (if appMutableStatic appSettings then staticDevel else static)+        (appStaticDir appSettings)+    let appFayCommandHandler = onCommand -    -- Initialize the logging middleware+    -- We need a log function to create a connection pool. We need a connection+    -- pool to create our foundation. And we need our foundation to get a+    -- logging function. To get out of this loop, we initially create a+    -- temporary foundation without a real connection pool, get a log function+    -- from there, and then create the real foundation.+    let mkFoundation appConnPool = App {..}+        tempFoundation = mkFoundation $ error "connPool forced in tempFoundation"+        logFunc = messageLoggerSource tempFoundation appLogger++    -- Create the database connection pool+    pool <- flip runLoggingT logFunc $ createPostgresqlPool+        (pgConnStr  $ appDatabaseConf appSettings)+        (pgPoolSize $ appDatabaseConf appSettings)++    -- Perform database migration using our application's logging settings.+    runLoggingT (runSqlPool (runMigration migrateAll) pool) logFunc++    -- Return the foundation+    return $ mkFoundation pool++-- | Convert our foundation to a WAI Application by calling @toWaiAppPlain@ and+-- applyng some additional middlewares.+makeApplication :: App -> IO Application+makeApplication foundation = do     logWare <- mkRequestLogger def         { outputFormat =-            if development+            if appDetailedRequestLogging $ appSettings foundation                 then Detailed True-                else Apache FromSocket-        , destination = RequestLogger.Logger $ loggerSet $ appLogger foundation+                else Apache+                        (if appIpFromHeader $ appSettings foundation+                            then FromFallback+                            else FromSocket)+        , destination = Logger $ loggerSet $ appLogger foundation         }      -- Create the WAI application and apply middlewares-    app <- toWaiAppPlain foundation-    let logFunc = messageLoggerSource foundation (appLogger foundation)-    return (logWare $ defaultMiddlewaresNoLogging app, logFunc)+    appPlain <- toWaiAppPlain foundation+    return $ logWare $ defaultMiddlewaresNoLogging appPlain --- | Loads up any necessary settings, creates your foundation datatype, and--- performs some initialization.-makeFoundation :: AppConfig DefaultEnv Extra -> IO App-makeFoundation conf = do-    manager <- newManager-    s <- staticSite-    dbconf <- withYamlEnvironment "config/postgresql.yml" (appEnv conf)-              Database.Persist.loadConfig >>=-              Database.Persist.applyEnv+-- | Warp settings for the given foundation value.+warpSettings :: App -> Settings+warpSettings foundation =+      setPort (appPort $ appSettings foundation)+    $ setHost (appHost $ appSettings foundation)+    $ setOnException (\_req e ->+        when (defaultShouldDisplayException e) $ messageLoggerSource+            foundation+            (appLogger foundation)+            $(qLocation >>= liftLoc)+            "yesod"+            LevelError+            (toLogStr $ "Exception from Warp: " ++ show e))+      defaultSettings -    loggerSet' <- newStdoutLoggerSet defaultBufSize-    (getter, _) <- clockDateCacher+-- | For yesod devel, return the Warp settings and WAI Application.+getApplicationDev :: IO (Settings, Application)+getApplicationDev = do+    settings <- loadAppSettings [configSettingsYml] [] useEnv+    foundation <- makeFoundation settings+    app <- makeApplication foundation+    wsettings <- getDevSettings $ warpSettings foundation+    return (wsettings, app) -    let logger = Yesod.Core.Types.Logger loggerSet' getter-        mkFoundation p = App-            { settings = conf-            , getStatic = s-            , connPool = p-            , httpManager = manager-            , persistConfig = dbconf-            , fayCommandHandler = onCommand-            , appLogger = logger-            }-        tempFoundation = mkFoundation $ error "connPool forced in tempFoundation"-        logFunc = messageLoggerSource tempFoundation logger+-- | main function for use by yesod devel+develMain :: IO ()+develMain = develMainHelper getApplicationDev -    p <- flip runLoggingT logFunc-       $ createPostgresqlPool (pgConnStr dbconf) (pgPoolSize dbconf)-    let foundation = mkFoundation p+-- | The @main@ function for an executable running this site.+appMain :: IO ()+appMain = do+    -- Get the settings from all relevant sources+    settings <- loadAppSettingsArgs+        -- fall back to compile-time values, set to [] to require values at runtime+        [configSettingsYmlValue] -    -- Perform database migration using our application's logging settings.-    flip runLoggingT logFunc-        (Database.Persist.runPool dbconf (runMigration migrateAll) p)+        -- allow environment variables to override+        useEnv -    return foundation+    -- Generate the foundation from the settings+    foundation <- makeFoundation settings --- for yesod devel-getApplicationDev :: IO (Int, Application)-getApplicationDev =-    defaultDevelApp loader (fmap fst . makeApplication)-  where-    loader = Yesod.Default.Config.loadConfig (configSettings Development)-        { csParseExtra = parseExtra-        }+    -- Generate a WAI Application from the foundation+    app <- makeApplication foundation +    -- Run the application with Warp+    runSettings (warpSettings foundation) app+ {-# START_FILE Foundation.hs #-} module Foundation where -import Prelude-import Yesod-import Yesod.Static-import Yesod.Auth-import Yesod.Auth.BrowserId-import Yesod.Default.Config-import Yesod.Default.Util (addStaticContentExternal)-import Network.HTTP.Client.Conduit (Manager, HasHttpManager (getHttpManager))-import qualified Settings-import Settings.Development (development)-import qualified Database.Persist-import Database.Persist.Sql (SqlBackend)-import Settings.StaticFiles-import Settings (widgetFile, Extra (..))+import ClassyPrelude.Yesod+import Database.Persist.Sql (ConnectionPool, runSqlPool) import Model-import Text.Hamlet (hamletFile)+import Settings+import Settings.StaticFiles+import Text.Hamlet          (hamletFile)+import Yesod.Auth+import Yesod.Auth.BrowserId (authBrowserId)+import Yesod.Core.Types     (Logger)+import Yesod.Default.Util   (addStaticContentExternal) import Yesod.Fay-import Yesod.Core.Types (Logger) --- | The site argument for your application. This can be a good place to+-- | The foundation datatype 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.-    , connPool :: Database.Persist.PersistConfigPool Settings.PersistConf -- ^ Database connection pool.-    , httpManager :: Manager-    , persistConfig :: Settings.PersistConf-    , fayCommandHandler :: CommandHandler App-    , appLogger :: Logger+    { appSettings          :: AppSettings+    , appStatic            :: Static -- ^ Settings for static file serving.+    , appConnPool          :: ConnectionPool -- ^ Database connection pool.+    , appHttpManager       :: Manager+    , appLogger            :: Logger+    , appFayCommandHandler :: CommandHandler App     }  instance HasHttpManager App where-    getHttpManager = httpManager---- Set up i18n messages. See the message folder.-mkMessage "App" "messages" "en"+    getHttpManager = appHttpManager  -- This is where we define all of the routes in our application. For a full -- explanation of the syntax, please see:@@ -184,12 +207,15 @@ -- explanation for this split. mkYesodData "App" $(parseRoutesFile "config/routes") +-- | A convenient synonym for creating forms. type Form x = Html -> MForm (HandlerT App IO) (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+    -- Controls the base of generated URLs. For more information on modifying,+    -- see: https://github.com/yesodweb/yesod/wiki/Overriding-approot+    approot = ApprootMaster $ appRoot . appSettings      -- Store session data on the client in encrypted cookies,     -- default session idle timeout is 120 minutes@@ -212,12 +238,6 @@             $(widgetFile "default-layout")         withUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet") -    -- This is done to provide an optimization for serving static files from-    -- a separate domain. Please see the staticRoot setting in Settings.hs-    urlRenderOverride y (StaticR s) =-        Just $ uncurry (joinPath y (Settings.staticRoot $ settings y)) $ renderRoute s-    urlRenderOverride _ _ = Nothing-     -- The page to be redirected to when authentication is required.     authRoute _ = Just $ AuthR LoginR @@ -232,21 +252,27 @@     -- and names them based on a hash of their content. This allows     -- expiration dates to be set far in the future without worry of     -- users receiving stale content.-    addStaticContent =-        addStaticContentExternal Right genFileName Settings.staticDir (StaticR . flip StaticRoute [])+    addStaticContent ext mime content = do+        master <- getYesod+        let staticDir = appStaticDir $ appSettings master+        addStaticContentExternal+            Right+            genFileName+            staticDir+            (StaticR . flip StaticRoute [])+            ext+            mime+            content       where         -- Generate a unique filename based on the content itself-        genFileName lbs-            | development = "autogen-" ++ base64md5 lbs-            | otherwise   = base64md5 lbs--    -- Place Javascript at bottom of the body tag so the rest of the page loads first-    jsLoader _ = BottomOfBody+        genFileName lbs = "autogen-" ++ base64md5 lbs      -- What messages should be logged. The following includes all messages when     -- in development, and warnings and errors in production.-    shouldLog _ _source level =-        development || level == LevelWarn || level == LevelError+    shouldLog app _source level =+        appShouldLogAll (appSettings app)+            || level == LevelWarn+            || level == LevelError      makeLogger = return . appLogger @@ -257,14 +283,16 @@      yesodFayCommand render command = do         master <- getYesod-        fayCommandHandler master render command+        appFayCommandHandler master render command  -- How to run database actions. instance YesodPersist App where     type YesodPersistBackend App = SqlBackend-    runDB = defaultRunDB persistConfig connPool+    runDB action = do+        master <- getYesod+        runSqlPool action $ appConnPool master instance YesodPersistRunner App where-    getDBRunner = defaultGetDBRunner connPool+    getDBRunner = defaultGetDBRunner appConnPool  instance YesodAuth App where     type AuthId App = UserId@@ -273,6 +301,8 @@     loginDest _ = HomeR     -- Where to send a user after logout     logoutDest _ = HomeR+    -- Override the above two destinations when a Referer: header is present+    redirectToReferer _ = True      getAuthId creds = runDB $ do         x <- getBy $ UniqueUser $ credsIdent creds@@ -287,7 +317,7 @@     -- You can add other plugins like BrowserID, email or OAuth here     authPlugins _ = [authBrowserId def] -    authHttpManager = httpManager+    authHttpManager = getHttpManager  instance YesodAuthPersist App @@ -296,23 +326,39 @@ instance RenderMessage App FormMessage where     renderMessage _ _ = defaultFormMessage --- | Get the 'Extra' value, used to hold data from the settings.yml file.-getExtra :: Handler Extra-getExtra = fmap (appExtra . settings) getYesod---- Note: previous versions of the scaffolding included a deliver function to--- send emails. Unfortunately, there are too many different options for us to--- give a reasonable default. Instead, the information is available on the--- wiki:+-- Note: Some functionality previously present in the scaffolding has been+-- moved to documentation in the Wiki. Following are some hopefully helpful+-- links: -- -- https://github.com/yesodweb/yesod/wiki/Sending-email+-- https://github.com/yesodweb/yesod/wiki/Serve-static-files-from-a-separate-domain+-- https://github.com/yesodweb/yesod/wiki/i18n-messages-in-the-scaffolding +{-# START_FILE Handler/Common.hs #-}+-- | Common handler functions.+module Handler.Common where++import Data.FileEmbed (embedFile)+import Import++-- These handlers embed files in the executable at compile time to avoid a+-- runtime dependency, and for efficiency.++getFaviconR :: Handler TypedContent+getFaviconR = return $ TypedContent "image/x-icon"+                     $ toContent $(embedFile "config/favicon.ico")++getRobotsR :: Handler TypedContent+getRobotsR = return $ TypedContent typePlain+                    $ toContent $(embedFile "config/robots.txt")+ {-# START_FILE Handler/Fay.hs #-} module Handler.Fay where +import Fay.Convert (readFromFay) import Import+import Prelude     ((!!)) import Yesod.Fay-import Fay.Convert (readFromFay)  fibs :: [Int] fibs = 0 : 1 : zipWith (+) fibs (drop 1 fibs)@@ -327,9 +373,8 @@ module Handler.Home where  import Import-import Language.Haskell.TH ( Exp(..) )-import Yesod.Form.Bootstrap3-    ( BootstrapFormLayout (..), renderBootstrap3, withSmallInput )+import Yesod.Form.Bootstrap3 (BootstrapFormLayout (..), renderBootstrap3,+                              withSmallInput)  -- This is a handler function for the GET request method on the HomeR -- resource pattern. All of your resource patterns are defined in@@ -347,7 +392,7 @@         aDomId <- newIdent         setTitle "Welcome To Yesod!"         $(widgetFile "homepage")-        $(fayFile' (ConE 'StaticR) "Home")+        $(fayFile "Home")  postHomeR :: Handler Html postHomeR = do@@ -372,41 +417,26 @@     ( module Import     ) where -import           Prelude              as Import hiding (head, init, last,-                                                 readFile, tail, writeFile)-import           Yesod                as Import hiding (Route (..))--import           Control.Applicative  as Import (pure, (<$>), (<*>))-import           Data.Text            as Import (Text)--import           Foundation           as Import-import           Model                as Import-import           Settings             as Import-import           Settings.Development as Import-import           Settings.StaticFiles as Import-import           SharedTypes          as Import--#if __GLASGOW_HASKELL__ >= 704-import           Data.Monoid          as Import-                                                 (Monoid (mappend, mempty, mconcat),-                                                 (<>))-#else-import           Data.Monoid          as Import-                                                 (Monoid (mappend, mempty, mconcat))+import ClassyPrelude.Yesod        as Import+import Foundation                 as Import+import Language.Haskell.TH.Syntax (Exp (ConE))+import Model                      as Import+import Settings                   as Import+import Settings.StaticFiles       as Import+import SharedTypes                as Import+import Yesod.Auth                 as Import+import Yesod.Core.Types           as Import (loggerSet)+import Yesod.Default.Config2      as Import+import Yesod.Fay                  (FayFile) -infixr 5 <>-(<>) :: Monoid m => m -> m -> m-(<>) = mappend-#endif+fayFile :: FayFile+fayFile = fayFile' (ConE 'StaticR)  {-# START_FILE Model.hs #-} module Model where -import Yesod-import Data.Text (Text)+import ClassyPrelude.Yesod import Database.Persist.Quasi-import Data.Typeable (Typeable)-import Prelude  -- You can define all of your database entities in the entities file. -- You can find more information on persistent and how to declare entities@@ -437,8 +467,8 @@                      Model                      Settings                      Settings.StaticFiles-                     Settings.Development                      SharedTypes+                     Handler.Common                      Handler.Fay                      Handler.Home @@ -464,19 +494,23 @@                 DeriveDataTypeable                 ViewPatterns                 TupleSections+                RecordWildCards      build-depends: base                          >= 4          && < 5-                 , yesod                         >= 1.4.0      && < 1.5+                 , yesod                         >= 1.4.1      && < 1.5                  , yesod-core                    >= 1.4.0      && < 1.5                  , yesod-auth                    >= 1.4.0      && < 1.5-                 , yesod-static                  >= 1.4.0      && < 1.5+                 , yesod-static                  >= 1.4.0.3    && < 1.5                  , yesod-form                    >= 1.4.0      && < 1.5                  , yesod-fay                     >= 0.7        && < 0.8                  , fay                           >= 0.21.2.1   && < 0.22+                 , classy-prelude                >= 0.10.2+                 , classy-prelude-conduit        >= 0.10.2+                 , classy-prelude-yesod          >= 0.10.2                  , bytestring                    >= 0.9        && < 0.11                  , text                          >= 0.11       && < 2.0                  , persistent                    >= 2.0        && < 2.2-                 , persistent-postgresql         >= 2.0        && < 2.2+                 , persistent-postgresql         >= 2.1.1      && < 2.2                  , persistent-template           >= 2.0        && < 2.2                  , template-haskell                  , shakespeare                   >= 2.0        && < 2.1@@ -492,10 +526,12 @@                  , monad-logger                  >= 0.3        && < 0.4                  , fast-logger                   >= 2.2        && < 2.3                  , wai-logger                    >= 2.2        && < 2.3--    -- see https://github.com/yesodweb/yesod/issues/814-    if !os(windows)-        build-depends: unix+                 , file-embed+                 , safe+                 , unordered-containers+                 , containers+                 , vector+                 , time  executable         PROJECTNAME     if flag(library-only)@@ -503,9 +539,7 @@      main-is:           main.hs     hs-source-dirs:    app-    build-depends:     base-                     , PROJECTNAME-                     , yesod+    build-depends:     base, PROJECTNAME      ghc-options:       -threaded -O2 -rtsopts -with-rtsopts=-N @@ -533,7 +567,7 @@      build-depends: base                  , PROJECTNAME-                 , yesod-test >= 1.4 && < 1.5+                 , yesod-test >= 1.4.2 && < 1.5                  , yesod-core                  , yesod                  , persistent@@ -542,6 +576,8 @@                  , monad-logger                  , transformers                  , hspec+                 , classy-prelude+                 , classy-prelude-yesod  {-# START_FILE Settings.hs #-} -- | Settings are centralized, as much as possible, into this file. This@@ -551,46 +587,82 @@ -- declared in the Foundation.hs file. module Settings where -import Prelude-import Text.Shakespeare.Text (st)-import Language.Haskell.TH.Syntax+import ClassyPrelude.Yesod+import Control.Exception           (throw)+import Data.Aeson                  (Result (..), fromJSON, withObject, (.!=),+                                    (.:?))+import Data.FileEmbed              (embedFile)+import Data.Yaml                   (decodeEither') import Database.Persist.Postgresql (PostgresConf)-import Yesod.Default.Config-import Yesod.Default.Util-import Data.Text (Text)-import Data.Yaml-import Control.Applicative-import Settings.Development-import Data.Default (def)-import Text.Hamlet+import Language.Haskell.TH.Syntax  (Exp, Name, Q)+import Network.Wai.Handler.Warp    (HostPreference)+import Yesod.Default.Config2       (applyEnvValue, configSettingsYml)+import Yesod.Default.Util          (WidgetFileSettings, widgetFileNoReload,+                                    widgetFileReload) import Yesod.Fay --- | Which Persistent backend this site is using.-type PersistConf = PostgresConf+-- | Runtime settings to configure this application. These settings can be+-- loaded from various sources: defaults, environment variables, config files,+-- theoretically even a database.+data AppSettings = AppSettings+    { appStaticDir              :: String+    -- ^ Directory from which to serve static files.+    , appDatabaseConf           :: PostgresConf+    -- ^ Configuration settings for accessing the database.+    , appRoot                   :: Text+    -- ^ Base for all generated URLs.+    , appHost                   :: HostPreference+    -- ^ Host/interface the server should bind to.+    , appPort                   :: Int+    -- ^ Port to listen on+    , appIpFromHeader           :: Bool+    -- ^ Get the IP address from the header when logging. Useful when sitting+    -- behind a reverse proxy. --- Static setting below. Changing these requires a recompile+    , appDetailedRequestLogging :: Bool+    -- ^ Use detailed request logging system+    , appShouldLogAll           :: Bool+    -- ^ Should all log messages be displayed?+    , appReloadTemplates        :: Bool+    -- ^ Use the reload version of templates+    , appMutableStatic          :: Bool+    -- ^ Assume that files in the static dir may change after compilation+    , appSkipCombining          :: Bool+    -- ^ Perform no stylesheet/script combining --- | The location of static files on your system. This is a file system--- path. The default value works properly with your scaffolded site.-staticDir :: FilePath-staticDir = "static"+    -- Example app-specific configuration values.+    , appCopyright              :: Text+    -- ^ Copyright text to appear in the footer of the page+    , appAnalytics              :: Maybe Text+    -- ^ Google Analytics code+    } --- | The base URL for your static files. As you can see by the default--- value, this can simply be "static" appended to your application root.--- A powerful optimization can be serving static files from a separate--- domain name. This allows you to use a web server optimized for static--- files, more easily set expires and cache values, and avoid possibly--- costly transference of cookies on static files. For more information,--- please see:---   http://code.google.com/speed/page-speed/docs/request.html#ServeFromCookielessDomain------ If you change the resource pattern for StaticR in Foundation.hs, you will--- have to make a corresponding change here.------ To see how this value is used, see urlRenderOverride in Foundation.hs-staticRoot :: AppConfig DefaultEnv x -> Text-staticRoot conf = [st|#{appRoot conf}/static|]+instance FromJSON AppSettings where+    parseJSON = withObject "AppSettings" $ \o -> do+        let defaultDev =+#if DEVELOPMENT+                True+#else+                False+#endif+        appStaticDir              <- o .: "static-dir"+        appDatabaseConf           <- o .: "database"+        appRoot                   <- o .: "approot"+        appHost                   <- fromString <$> o .: "host"+        appPort                   <- o .: "port"+        appIpFromHeader           <- o .: "ip-from-header" +        appDetailedRequestLogging <- o .:? "detailed-logging" .!= defaultDev+        appShouldLogAll           <- o .:? "should-log-all"   .!= defaultDev+        appReloadTemplates        <- o .:? "reload-templates" .!= defaultDev+        appMutableStatic          <- o .:? "mutable-static"   .!= defaultDev+        appSkipCombining          <- o .:? "skip-combining"   .!= defaultDev++        appCopyright              <- o .: "copyright"+        appAnalytics              <- o .:? "analytics"++        return AppSettings {..}+ -- | Settings for 'widgetFile', such as which template languages to support and -- default Hamlet settings. --@@ -599,23 +671,26 @@ -- https://github.com/yesodweb/yesod/wiki/Overriding-widgetFile widgetFileSettings :: WidgetFileSettings widgetFileSettings = def-    { wfsHamletSettings = defaultHamletSettings-        { hamletNewlines = AlwaysNewlines-        }-    } +-- | How static files should be combined.+combineSettings :: CombineSettings+combineSettings = def+ -- The rest of this file contains settings which rarely need changing by a -- user.  widgetFile :: String -> Q Exp-widgetFile = (if development then widgetFileReload-                             else widgetFileNoReload)+widgetFile = (if appReloadTemplates compileTimeAppSettings+                then widgetFileReload+                else widgetFileNoReload)               widgetFileSettings  fayFile' :: Exp -> FayFile-fayFile' staticR moduleName-    | development = fayFileReload settings-    | otherwise   = fayFileProd settings+fayFile' staticR moduleName =+    (if appReloadTemplates compileTimeAppSettings+        then fayFileReload+        else fayFileProd)+     settings   where     settings = (yesodFaySettings moduleName)         { yfsSeparateRuntime = Just ("static", staticR)@@ -624,68 +699,48 @@         , yfsPackages = ["fay-dom"]         } -data Extra = Extra-    { extraCopyright :: Text-    , extraAnalytics :: Maybe Text -- ^ Google Analytics-    } deriving Show+-- | Raw bytes at compile time of @config/settings.yml@+configSettingsYmlBS :: ByteString+configSettingsYmlBS = $(embedFile configSettingsYml) -parseExtra :: DefaultEnv -> Object -> Parser Extra-parseExtra _ o = Extra-    <$> o .:  "copyright"-    <*> o .:? "analytics"+-- | @config/settings.yml@, parsed to a @Value@.+configSettingsYmlValue :: Value+configSettingsYmlValue = either throw id $ decodeEither' configSettingsYmlBS -{-# START_FILE Settings/Development.hs #-}-module Settings.Development where+-- | A version of @AppSettings@ parsed at compile time from @config/settings.yml@.+compileTimeAppSettings :: AppSettings+compileTimeAppSettings =+    case fromJSON $ applyEnvValue False mempty configSettingsYmlValue of+        Error e -> error e+        Success settings -> settings -import Prelude+-- The following two functions can be used to combine multiple CSS or JS files+-- at compile time to decrease the number of http requests.+-- Sample usage (inside a Widget):+--+-- > $(combineStylesheets 'StaticR [style1_css, style2_css]) -development :: Bool-development =-#if DEVELOPMENT-  True-#else-  False-#endif+combineStylesheets :: Name -> [Route Static] -> Q Exp+combineStylesheets = combineStylesheets'+    (appSkipCombining compileTimeAppSettings)+    combineSettings -production :: Bool-production = not development+combineScripts :: Name -> [Route Static] -> Q Exp+combineScripts = combineScripts'+    (appSkipCombining compileTimeAppSettings)+    combineSettings  {-# START_FILE Settings/StaticFiles.hs #-} module Settings.StaticFiles where -import Prelude (IO)-import Yesod.Static-import qualified Yesod.Static as Static-import Settings (staticDir)-import Settings.Development-import Language.Haskell.TH (Q, Exp, Name)-import Data.Default (def)---- | use this to create your static file serving site-staticSite :: IO Static.Static-staticSite = if development then Static.staticDevel staticDir-                            else Static.static      staticDir+import Settings     (appStaticDir, compileTimeAppSettings)+import Yesod.Static (staticFiles)  -- | This generates easy references to files in the static directory at compile time, --   giving you compile-time verification that referenced files exist. --   Warning: any files added to your static directory during run-time can't be --   accessed this way. You'll have to use their FilePath or URL to access them.-$(staticFiles Settings.staticDir)--combineSettings :: CombineSettings-combineSettings = def---- The following two functions can be used to combine multiple CSS or JS files--- at compile time to decrease the number of http requests.--- Sample usage (inside a Widget):------ > $(combineStylesheets 'StaticR [style1_css, style2_css])--combineStylesheets :: Name -> [Route Static] -> Q Exp-combineStylesheets = combineStylesheets' development combineSettings--combineScripts :: Name -> [Route Static] -> Q Exp-combineScripts = combineScripts' development combineSettings+staticFiles (appStaticDir compileTimeAppSettings)  {-# START_FILE app/DevelMain.hs #-} -- | Development version to be run inside GHCi.@@ -752,19 +807,24 @@ start :: MVar () -- ^ Written to when the thread is killed.       -> IO ThreadId start done = do-    (port,app) <- getApplicationDev-    forkIO (finally (runSettings (setPort port defaultSettings) app)+    (settings,app) <- getApplicationDev+    forkIO (finally (runSettings settings app)                     (putMVar done ())) +{-# START_FILE app/devel.hs #-}+{-# LANGUAGE PackageImports #-}+import "PROJECTNAME" Application (develMain)+import Prelude (IO)++main :: IO ()+main = develMain+ {-# START_FILE app/main.hs #-}-import Prelude              (IO)-import Yesod.Default.Config (fromArgs)-import Yesod.Default.Main   (defaultMainLog)-import Settings             (parseExtra)-import Application          (makeApplication)+import Prelude     (IO)+import Application (appMain)  main :: IO ()-main = defaultMainLog (fromArgs parseExtra) makeApplication+main = appMain  {-# START_FILE BASE64 config/favicon.ico #-} AAABAAIAEBAAAAEAIABoBAAAJgAAABAQAgABAAEAsAAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAA@@ -869,46 +929,11 @@   -- By default this file is used in Model.hs (which is imported by Foundation.hs) -{-# START_FILE config/postgresql.yml #-}-# NOTE: These settings can be overridden by environment variables as well, in-# particular:-#-#    PGHOST-#    PGPORT-#    PGUSER-#    PGPASS-#    PGDATABASE--Default: &defaults-  user: PROJECTNAME-  password: PROJECTNAME-  host: localhost-  port: 5432-  database: PROJECTNAME-  poolsize: 10--Development:-  <<: *defaults--Testing:-  database: PROJECTNAME_test-  <<: *defaults--Staging:-  database: PROJECTNAME_staging-  poolsize: 100-  <<: *defaults--Production:-  database: PROJECTNAME_production-  poolsize: 100-  <<: *defaults- {-# START_FILE config/robots.txt #-} User-agent: *  {-# START_FILE config/routes #-}-/static      StaticR  Static  getStatic+/static      StaticR  Static  appStatic /auth        AuthR    Auth    getAuth /fay-command FaySiteR FaySite getFaySite @@ -918,152 +943,36 @@ / HomeR GET POST  {-# START_FILE config/settings.yml #-}-Default: &defaults-  host: "*4" # any IPv4 host-  port: 3000-  approot: "http://localhost:3000"-  copyright: Insert copyright statement here-  #analytics: UA-YOURCODE--Development:-  <<: *defaults--Testing:-  <<: *defaults--Staging:-  <<: *defaults--Production:-  #approot: "http://www.example.com"-  <<: *defaults--{-# START_FILE deploy/Procfile #-}-# Free deployment to Heroku.-#-#   !! Warning: You must use a 64 bit machine to compile !!-#-#   This could mean using a virtual machine. Give your VM as much memory as you can to speed up linking.-#-# Basic Yesod setup:-#-# * Move this file out of the deploy directory and into your root directory-#-#     mv deploy/Procfile ./-#-# * Create an empty package.json-#     echo '{ "name": "PROJECTNAME", "version": "0.0.1", "dependencies": {} }' >> package.json-#-# Postgresql Yesod setup:-#-# * add dependencies on the "heroku", "aeson" and "unordered-containers" packages in your cabal file-#-# * add code in Application.hs to use the heroku package and load the connection parameters.-#   The below works for Postgresql.-#-#   import Data.HashMap.Strict as H-#   import Data.Aeson.Types as AT-#   #ifndef DEVELOPMENT-#   import qualified Web.Heroku-#   #endif-#-#-#-#   makeFoundation :: AppConfig DefaultEnv Extra -> Logger -> IO App-#   makeFoundation conf setLogger = do-#       manager <- newManager def-#       s <- staticSite-#       hconfig <- loadHerokuConfig-#       dbconf <- withYamlEnvironment "config/postgresql.yml" (appEnv conf)-#                 (Database.Persist.Store.loadConfig . combineMappings hconfig) >>=-#                 Database.Persist.Store.applyEnv-#       p <- Database.Persist.Store.createPoolConfig (dbconf :: Settings.PersistConfig)-#       Database.Persist.Store.runPool dbconf (runMigration migrateAll) p-#       return $ App conf setLogger s p manager dbconf-#-#   #ifndef DEVELOPMENT-#   canonicalizeKey :: (Text, val) -> (Text, val)-#   canonicalizeKey ("dbname", val) = ("database", val)-#   canonicalizeKey pair = pair-#-#   toMapping :: [(Text, Text)] -> AT.Value-#   toMapping xs = AT.Object $ M.fromList $ map (\(key, val) -> (key, AT.String val)) xs-#   #endif-#-#   combineMappings :: AT.Value -> AT.Value -> AT.Value-#   combineMappings (AT.Object m1) (AT.Object m2) = AT.Object $ m1 `M.union` m2-#   combineMappings _ _ = error "Data.Object is not a Mapping."-#-#   loadHerokuConfig :: IO AT.Value-#   loadHerokuConfig = do-#   #ifdef DEVELOPMENT-#       return $ AT.Object M.empty-#   #else-#       Web.Heroku.dbConnParams >>= return . toMapping . map canonicalizeKey-#   #endif--+static-dir:     "_env:STATIC_DIR:static"+host:           "_env:HOST:*4" # any IPv4 host+port:           "_env:PORT:3000"+approot:        "_env:APPROOT:http://localhost:3000"+ip-from-header: "_env:IP_FROM_HEADER:false" -# Heroku setup:-# Find the Heroku guide. Roughly:-#-# * sign up for a heroku account and register your ssh key-# * create a new application on the *cedar* stack-#-# * make your Yesod project the git repository for that application-# * create a deploy branch-#-#     git checkout -b deploy-#-# Repeat these steps to deploy:-# * add your web executable binary (referenced below) to the git repository-#-#     git checkout deploy-#     git add ./dist/build/PROJECTNAME/PROJECTNAME-#     git commit -m deploy-#-# * push to Heroku+# Optional values with the following production defaults.+# In development, they default to the inverse. #-#     git push heroku deploy:master---# Heroku configuration that runs your app-web: ./dist/build/PROJECTNAME/PROJECTNAME production -p $PORT--{-# START_FILE devel.hs #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE PackageImports #-}-import "PROJECTNAME" Application (getApplicationDev)-import Network.Wai.Handler.Warp-    (runSettings, defaultSettings, setPort)-import Control.Concurrent (forkIO)-import System.Directory (doesFileExist, removeFile)-import System.Exit (exitSuccess)-import Control.Concurrent (threadDelay)--#ifndef mingw32_HOST_OS-import System.Posix.Signals (installHandler, sigINT, Handler(Catch))-#endif--main :: IO ()-main = do-#ifndef mingw32_HOST_OS-    _ <- installHandler sigINT (Catch $ return ()) Nothing-#endif+# development: false+# detailed-logging: false+# should-log-all: false+# reload-templates: false+# mutable-static: false+# skip-combining: false -    putStrLn "Starting devel application"-    (port, app) <- getApplicationDev-    forkIO $ runSettings (setPort port defaultSettings) app-    loop+database:+  user:     "_env:PGUSER:PROJECTNAME"+  password: "_env:PGPASS:PROJECTNAME"+  host:     "_env:PGHOST:localhost"+  port:     "_env:PGPORT:5432"+  database: "_env:PGDATABASE:PROJECTNAME"+  poolsize: "_env:PGPOOLSIZE:10" -loop :: IO ()-loop = do-  threadDelay 100000-  e <- doesFileExist "yesod-devel/devel-terminate"-  if e then terminateDevel else loop+copyright: Insert copyright statement here+#analytics: UA-YOURCODE -terminateDevel :: IO ()-terminateDevel = exitSuccess+{-# START_FILE config/test-settings.yml #-}+database:+  database: PROJECTNAME_test  {-# START_FILE fay-shared/SharedTypes.hs #-} {-# LANGUAGE NoImplicitPrelude #-}@@ -1120,9 +1029,6 @@         index <- parseInt indexS         call (GetFib index) $ setInnerHTML result . T.pack . show -{-# START_FILE messages/en.msg #-}-Hello: Hello- {-# START_FILE static/css/bootstrap.css #-} /*!  * Bootstrap v3.2.0 (http://getbootstrap.com)@@ -9087,9 +8993,9 @@             <div id="main" role="main">               ^{pageBody pc}             <footer>-                #{extraCopyright $ appExtra $ settings master}+                #{appCopyright $ appSettings master} -        $maybe analytics <- extraAnalytics $ appExtra $ settings master+        $maybe analytics <- appAnalytics $ appSettings master             <script>               if(!window.location.href.match(/localhost/)){                 window._gaq = [['_setAccount','#{analytics}'],['_trackPageview'],['_trackPageLoadTime']];@@ -9112,7 +9018,7 @@ ^{widget}  {-# START_FILE templates/homepage.hamlet #-}-<h1>_{MsgHello}+<h1>Welcome to Yesod!  <ol>   <li>Now that you have a working project you should use the #@@ -9168,92 +9074,88 @@     color: #990 } -{-# START_FILE test/Handler/HomeSpec.hs #-}-module Handler.HomeSpec-    ( spec-    ) where+{-# START_FILE test/Handler/CommonSpec.hs #-}+module Handler.CommonSpec (spec) where  import TestImport-import qualified Data.List as L  spec :: Spec-spec =-    ydescribe "These are some example tests" $ do--        yit "loads the index and checks it looks right" $ do-            get HomeR+spec = withApp $ do+    describe "robots.txt" $ do+        it "gives a 200" $ do+            get RobotsR             statusIs 200-            htmlAllContain "h1" "Hello"+        it "has correct User-agent" $ do+            get RobotsR+            bodyContains "User-agent: *"+    describe "favicon.ico" $ do+        it "gives a 200" $ do+            get FaviconR+            statusIs 200 -            request $ do-                setMethod "POST"-                setUrl HomeR-                addNonce-                fileByLabel "Choose a file" "test/Spec.hs" "text/plain" -- talk about self-reference-                byLabel "What's on the file?" "Some Content"+{-# START_FILE test/Handler/HomeSpec.hs #-}+module Handler.HomeSpec (spec) where -            statusIs 200-            -- more debugging printBody-            htmlCount ".message" 1-            htmlAllContain ".message" "Some Content"-            htmlAllContain ".message" "text/plain"+import TestImport -        -- This is a simple example of using a database access in a test.  The-        -- test will succeed for a fresh scaffolded site with an empty database,-        -- but will fail on an existing database with a non-empty user table.-        yit "leaves the user table empty" $ do-            get HomeR-            statusIs 200-            users <- runDB $ selectList ([] :: [Filter User]) []-            assertEqual "user table empty" 0 $ L.length users+spec :: Spec+spec = withApp $ do+    it "loads the index and checks it looks right" $ do+        get HomeR+        statusIs 200+        htmlAllContain "h1" "Welcome to Yesod" -{-# START_FILE test/Spec.hs #-}-module Main where+        request $ do+            setMethod "POST"+            setUrl HomeR+            addNonce+            fileByLabel "Choose a file" "test/Spec.hs" "text/plain" -- talk about self-reference+            byLabel "What's on the file?" "Some Content" -import Import-import Yesod.Default.Config-import Yesod.Test-import Test.Hspec (hspec)-import Application (makeFoundation)+        statusIs 200+        -- more debugging printBody+        htmlCount ".message" 1+        htmlAllContain ".message" "Some Content"+        htmlAllContain ".message" "text/plain" -import qualified Handler.HomeSpec+    -- This is a simple example of using a database access in a test.  The+    -- test will succeed for a fresh scaffolded site with an empty database,+    -- but will fail on an existing database with a non-empty user table.+    it "leaves the user table empty" $ do+        get HomeR+        statusIs 200+        users <- runDB $ selectList ([] :: [Filter User]) []+        assertEqual "user table empty" 0 $ length users -main :: IO ()-main = do-    conf <- Yesod.Default.Config.loadConfig $ (configSettings Testing)-                { csParseExtra = parseExtra-                }-    foundation <- makeFoundation conf-    hspec $ do-        yesodSpec foundation $ do-            Handler.HomeSpec.spec+{-# START_FILE test/Spec.hs #-}+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}  {-# START_FILE test/TestImport.hs #-} module TestImport-    ( module Yesod.Test-    , module Model-    , module Foundation-    , module Database.Persist-    , module Prelude-    , runDB-    , Spec-    , Example+    ( module TestImport+    , module X     ) where -import Yesod.Test-import Database.Persist hiding (get)-import Database.Persist.Sql (SqlPersistM, runSqlPersistMPool)-import Control.Monad.IO.Class (liftIO)-import Prelude--import Foundation-import Model--type Spec = YesodSpec App-type Example = YesodExample App+import Application           (makeFoundation)+import ClassyPrelude         as X+import Database.Persist      as X hiding (get)+import Database.Persist.Sql  (SqlPersistM, runSqlPersistMPool)+import Foundation            as X+import Model                 as X+import Test.Hspec            as X+import Yesod.Default.Config2 (ignoreEnv, loadAppSettings)+import Yesod.Test            as X -runDB :: SqlPersistM a -> Example a+runDB :: SqlPersistM a -> YesodExample App a runDB query = do-    pool <- fmap connPool getTestYesod+    pool <- fmap appConnPool getTestYesod     liftIO $ runSqlPersistMPool query pool++withApp :: SpecWith App -> Spec+withApp = before $ do+    settings <- loadAppSettings+        ["config/test-settings.yml", "config/settings.yml"]+        []+        ignoreEnv+    makeFoundation settings 
hsfiles/postgres.hsfiles view
@@ -28,32 +28,31 @@ {-# START_FILE Application.hs #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Application-    ( makeApplication-    , getApplicationDev+    ( getApplicationDev+    , appMain+    , develMain     , makeFoundation     ) where +import Control.Monad.Logger                 (liftLoc, runLoggingT)+import Database.Persist.Postgresql          (createPostgresqlPool, pgConnStr,+                                             pgPoolSize, runSqlPool) import Import-import Yesod.Auth-import Yesod.Default.Config-import Yesod.Default.Main-import Yesod.Default.Handlers-import Network.Wai.Middleware.RequestLogger-    ( mkRequestLogger, outputFormat, OutputFormat (..), IPAddrSource (..), destination-    )-import qualified Network.Wai.Middleware.RequestLogger as RequestLogger-import qualified Database.Persist-import Database.Persist.Sql (runMigration)-import Database.Persist.Postgresql (createPostgresqlPool, pgConnStr, pgPoolSize)-import Network.HTTP.Client.Conduit (newManager)-import Control.Monad.Logger (runLoggingT)-import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize)-import Network.Wai.Logger (clockDateCacher)-import Data.Default (def)-import Yesod.Core.Types (loggerSet, Logger (Logger))+import Language.Haskell.TH.Syntax           (qLocation)+import Network.Wai.Handler.Warp             (Settings, defaultSettings,+                                             defaultShouldDisplayException,+                                             runSettings, setHost,+                                             setOnException, setPort)+import Network.Wai.Middleware.RequestLogger (Destination (Logger),+                                             IPAddrSource (..),+                                             OutputFormat (..), destination,+                                             mkRequestLogger, outputFormat)+import System.Log.FastLogger                (defaultBufSize, newStdoutLoggerSet,+                                             toLogStr)  -- Import all relevant handler modules here. -- Don't forget to add new modules to your cabal file!+import Handler.Common import Handler.Home  -- This line actually creates our YesodDispatch instance. It is the second half@@ -61,112 +60,136 @@ -- 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+-- | This function allocates resources (such as a database connection pool),+-- performs initialization and return a foundation datatype value. This is also+-- the place to put your migrate statements to have automatic database -- migrations handled by Yesod.-makeApplication :: AppConfig DefaultEnv Extra -> IO (Application, LogFunc)-makeApplication conf = do-    foundation <- makeFoundation conf+makeFoundation :: AppSettings -> IO App+makeFoundation appSettings = do+    -- Some basic initializations: HTTP connection manager, logger, and static+    -- subsite.+    appHttpManager <- newManager+    appLogger <- newStdoutLoggerSet defaultBufSize >>= makeYesodLogger+    appStatic <-+        (if appMutableStatic appSettings then staticDevel else static)+        (appStaticDir appSettings) -    -- Initialize the logging middleware+    -- We need a log function to create a connection pool. We need a connection+    -- pool to create our foundation. And we need our foundation to get a+    -- logging function. To get out of this loop, we initially create a+    -- temporary foundation without a real connection pool, get a log function+    -- from there, and then create the real foundation.+    let mkFoundation appConnPool = App {..}+        tempFoundation = mkFoundation $ error "connPool forced in tempFoundation"+        logFunc = messageLoggerSource tempFoundation appLogger++    -- Create the database connection pool+    pool <- flip runLoggingT logFunc $ createPostgresqlPool+        (pgConnStr  $ appDatabaseConf appSettings)+        (pgPoolSize $ appDatabaseConf appSettings)++    -- Perform database migration using our application's logging settings.+    runLoggingT (runSqlPool (runMigration migrateAll) pool) logFunc++    -- Return the foundation+    return $ mkFoundation pool++-- | Convert our foundation to a WAI Application by calling @toWaiAppPlain@ and+-- applyng some additional middlewares.+makeApplication :: App -> IO Application+makeApplication foundation = do     logWare <- mkRequestLogger def         { outputFormat =-            if development+            if appDetailedRequestLogging $ appSettings foundation                 then Detailed True-                else Apache FromSocket-        , destination = RequestLogger.Logger $ loggerSet $ appLogger foundation+                else Apache+                        (if appIpFromHeader $ appSettings foundation+                            then FromFallback+                            else FromSocket)+        , destination = Logger $ loggerSet $ appLogger foundation         }      -- Create the WAI application and apply middlewares-    app <- toWaiAppPlain foundation-    let logFunc = messageLoggerSource foundation (appLogger foundation)-    return (logWare $ defaultMiddlewaresNoLogging app, logFunc)+    appPlain <- toWaiAppPlain foundation+    return $ logWare $ defaultMiddlewaresNoLogging appPlain --- | Loads up any necessary settings, creates your foundation datatype, and--- performs some initialization.-makeFoundation :: AppConfig DefaultEnv Extra -> IO App-makeFoundation conf = do-    manager <- newManager-    s <- staticSite-    dbconf <- withYamlEnvironment "config/postgresql.yml" (appEnv conf)-              Database.Persist.loadConfig >>=-              Database.Persist.applyEnv+-- | Warp settings for the given foundation value.+warpSettings :: App -> Settings+warpSettings foundation =+      setPort (appPort $ appSettings foundation)+    $ setHost (appHost $ appSettings foundation)+    $ setOnException (\_req e ->+        when (defaultShouldDisplayException e) $ messageLoggerSource+            foundation+            (appLogger foundation)+            $(qLocation >>= liftLoc)+            "yesod"+            LevelError+            (toLogStr $ "Exception from Warp: " ++ show e))+      defaultSettings -    loggerSet' <- newStdoutLoggerSet defaultBufSize-    (getter, _) <- clockDateCacher+-- | For yesod devel, return the Warp settings and WAI Application.+getApplicationDev :: IO (Settings, Application)+getApplicationDev = do+    settings <- loadAppSettings [configSettingsYml] [] useEnv+    foundation <- makeFoundation settings+    app <- makeApplication foundation+    wsettings <- getDevSettings $ warpSettings foundation+    return (wsettings, app) -    let logger = Yesod.Core.Types.Logger loggerSet' getter-        mkFoundation p = App-            { settings = conf-            , getStatic = s-            , connPool = p-            , httpManager = manager-            , persistConfig = dbconf-            , appLogger = logger-            }-        tempFoundation = mkFoundation $ error "connPool forced in tempFoundation"-        logFunc = messageLoggerSource tempFoundation logger+-- | main function for use by yesod devel+develMain :: IO ()+develMain = develMainHelper getApplicationDev -    p <- flip runLoggingT logFunc-       $ createPostgresqlPool (pgConnStr dbconf) (pgPoolSize dbconf)-    let foundation = mkFoundation p+-- | The @main@ function for an executable running this site.+appMain :: IO ()+appMain = do+    -- Get the settings from all relevant sources+    settings <- loadAppSettingsArgs+        -- fall back to compile-time values, set to [] to require values at runtime+        [configSettingsYmlValue] -    -- Perform database migration using our application's logging settings.-    flip runLoggingT logFunc-        (Database.Persist.runPool dbconf (runMigration migrateAll) p)+        -- allow environment variables to override+        useEnv -    return foundation+    -- Generate the foundation from the settings+    foundation <- makeFoundation settings --- for yesod devel-getApplicationDev :: IO (Int, Application)-getApplicationDev =-    defaultDevelApp loader (fmap fst . makeApplication)-  where-    loader = Yesod.Default.Config.loadConfig (configSettings Development)-        { csParseExtra = parseExtra-        }+    -- Generate a WAI Application from the foundation+    app <- makeApplication foundation +    -- Run the application with Warp+    runSettings (warpSettings foundation) app+ {-# START_FILE Foundation.hs #-} module Foundation where -import Prelude-import Yesod-import Yesod.Static-import Yesod.Auth-import Yesod.Auth.BrowserId-import Yesod.Default.Config-import Yesod.Default.Util (addStaticContentExternal)-import Network.HTTP.Client.Conduit (Manager, HasHttpManager (getHttpManager))-import qualified Settings-import Settings.Development (development)-import qualified Database.Persist-import Database.Persist.Sql (SqlBackend)-import Settings.StaticFiles-import Settings (widgetFile, Extra (..))+import ClassyPrelude.Yesod+import Database.Persist.Sql (ConnectionPool, runSqlPool) import Model-import Text.Jasmine (minifym)-import Text.Hamlet (hamletFile)-import Yesod.Core.Types (Logger)+import Settings+import Settings.StaticFiles+import Text.Hamlet          (hamletFile)+import Text.Jasmine         (minifym)+import Yesod.Auth+import Yesod.Auth.BrowserId (authBrowserId)+import Yesod.Core.Types     (Logger)+import Yesod.Default.Util   (addStaticContentExternal) --- | The site argument for your application. This can be a good place to+-- | The foundation datatype 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.-    , connPool :: Database.Persist.PersistConfigPool Settings.PersistConf -- ^ Database connection pool.-    , httpManager :: Manager-    , persistConfig :: Settings.PersistConf-    , appLogger :: Logger+    { appSettings    :: AppSettings+    , appStatic      :: Static -- ^ Settings for static file serving.+    , appConnPool    :: ConnectionPool -- ^ Database connection pool.+    , appHttpManager :: Manager+    , appLogger      :: Logger     }  instance HasHttpManager App where-    getHttpManager = httpManager---- Set up i18n messages. See the message folder.-mkMessage "App" "messages" "en"+    getHttpManager = appHttpManager  -- This is where we define all of the routes in our application. For a full -- explanation of the syntax, please see:@@ -177,12 +200,15 @@ -- explanation for this split. mkYesodData "App" $(parseRoutesFile "config/routes") +-- | A convenient synonym for creating forms. type Form x = Html -> MForm (HandlerT App IO) (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+    -- Controls the base of generated URLs. For more information on modifying,+    -- see: https://github.com/yesodweb/yesod/wiki/Overriding-approot+    approot = ApprootMaster $ appRoot . appSettings      -- Store session data on the client in encrypted cookies,     -- default session idle timeout is 120 minutes@@ -205,12 +231,6 @@             $(widgetFile "default-layout")         withUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet") -    -- This is done to provide an optimization for serving static files from-    -- a separate domain. Please see the staticRoot setting in Settings.hs-    urlRenderOverride y (StaticR s) =-        Just $ uncurry (joinPath y (Settings.staticRoot $ settings y)) $ renderRoute s-    urlRenderOverride _ _ = Nothing-     -- The page to be redirected to when authentication is required.     authRoute _ = Just $ AuthR LoginR @@ -225,30 +245,38 @@     -- and names them based on a hash of their content. This allows     -- expiration dates to be set far in the future without worry of     -- users receiving stale content.-    addStaticContent =-        addStaticContentExternal minifym genFileName Settings.staticDir (StaticR . flip StaticRoute [])+    addStaticContent ext mime content = do+        master <- getYesod+        let staticDir = appStaticDir $ appSettings master+        addStaticContentExternal+            minifym+            genFileName+            staticDir+            (StaticR . flip StaticRoute [])+            ext+            mime+            content       where         -- Generate a unique filename based on the content itself-        genFileName lbs-            | development = "autogen-" ++ base64md5 lbs-            | otherwise   = base64md5 lbs--    -- Place Javascript at bottom of the body tag so the rest of the page loads first-    jsLoader _ = BottomOfBody+        genFileName lbs = "autogen-" ++ base64md5 lbs      -- What messages should be logged. The following includes all messages when     -- in development, and warnings and errors in production.-    shouldLog _ _source level =-        development || level == LevelWarn || level == LevelError+    shouldLog app _source level =+        appShouldLogAll (appSettings app)+            || level == LevelWarn+            || level == LevelError      makeLogger = return . appLogger  -- How to run database actions. instance YesodPersist App where     type YesodPersistBackend App = SqlBackend-    runDB = defaultRunDB persistConfig connPool+    runDB action = do+        master <- getYesod+        runSqlPool action $ appConnPool master instance YesodPersistRunner App where-    getDBRunner = defaultGetDBRunner connPool+    getDBRunner = defaultGetDBRunner appConnPool  instance YesodAuth App where     type AuthId App = UserId@@ -257,6 +285,8 @@     loginDest _ = HomeR     -- Where to send a user after logout     logoutDest _ = HomeR+    -- Override the above two destinations when a Referer: header is present+    redirectToReferer _ = True      getAuthId creds = runDB $ do         x <- getBy $ UniqueUser $ credsIdent creds@@ -271,7 +301,7 @@     -- You can add other plugins like BrowserID, email or OAuth here     authPlugins _ = [authBrowserId def] -    authHttpManager = httpManager+    authHttpManager = getHttpManager  instance YesodAuthPersist App @@ -280,23 +310,38 @@ instance RenderMessage App FormMessage where     renderMessage _ _ = defaultFormMessage --- | Get the 'Extra' value, used to hold data from the settings.yml file.-getExtra :: Handler Extra-getExtra = fmap (appExtra . settings) getYesod---- Note: previous versions of the scaffolding included a deliver function to--- send emails. Unfortunately, there are too many different options for us to--- give a reasonable default. Instead, the information is available on the--- wiki:+-- Note: Some functionality previously present in the scaffolding has been+-- moved to documentation in the Wiki. Following are some hopefully helpful+-- links: -- -- https://github.com/yesodweb/yesod/wiki/Sending-email+-- https://github.com/yesodweb/yesod/wiki/Serve-static-files-from-a-separate-domain+-- https://github.com/yesodweb/yesod/wiki/i18n-messages-in-the-scaffolding +{-# START_FILE Handler/Common.hs #-}+-- | Common handler functions.+module Handler.Common where++import Data.FileEmbed (embedFile)+import Import++-- These handlers embed files in the executable at compile time to avoid a+-- runtime dependency, and for efficiency.++getFaviconR :: Handler TypedContent+getFaviconR = return $ TypedContent "image/x-icon"+                     $ toContent $(embedFile "config/favicon.ico")++getRobotsR :: Handler TypedContent+getRobotsR = return $ TypedContent typePlain+                    $ toContent $(embedFile "config/robots.txt")+ {-# START_FILE Handler/Home.hs #-} module Handler.Home where  import Import-import Yesod.Form.Bootstrap3-    ( BootstrapFormLayout (..), renderBootstrap3, withSmallInput )+import Yesod.Form.Bootstrap3 (BootstrapFormLayout (..), renderBootstrap3,+                              withSmallInput)  -- This is a handler function for the GET request method on the HomeR -- resource pattern. All of your resource patterns are defined in@@ -338,40 +383,20 @@     ( module Import     ) where -import           Prelude              as Import hiding (head, init, last,-                                                 readFile, tail, writeFile)-import           Yesod                as Import hiding (Route (..))--import           Control.Applicative  as Import (pure, (<$>), (<*>))-import           Data.Text            as Import (Text)--import           Foundation           as Import-import           Model                as Import-import           Settings             as Import-import           Settings.Development as Import-import           Settings.StaticFiles as Import--#if __GLASGOW_HASKELL__ >= 704-import           Data.Monoid          as Import-                                                 (Monoid (mappend, mempty, mconcat),-                                                 (<>))-#else-import           Data.Monoid          as Import-                                                 (Monoid (mappend, mempty, mconcat))--infixr 5 <>-(<>) :: Monoid m => m -> m -> m-(<>) = mappend-#endif+import ClassyPrelude.Yesod   as Import+import Foundation            as Import+import Model                 as Import+import Settings              as Import+import Settings.StaticFiles  as Import+import Yesod.Auth            as Import+import Yesod.Core.Types      as Import (loggerSet)+import Yesod.Default.Config2 as Import  {-# START_FILE Model.hs #-} module Model where -import Yesod-import Data.Text (Text)+import ClassyPrelude.Yesod import Database.Persist.Quasi-import Data.Typeable (Typeable)-import Prelude  -- You can define all of your database entities in the entities file. -- You can find more information on persistent and how to declare entities@@ -401,7 +426,7 @@                      Model                      Settings                      Settings.StaticFiles-                     Settings.Development+                     Handler.Common                      Handler.Home      if flag(dev) || flag(library-only)@@ -425,17 +450,21 @@                 DeriveDataTypeable                 ViewPatterns                 TupleSections+                RecordWildCards      build-depends: base                          >= 4          && < 5-                 , yesod                         >= 1.4.0      && < 1.5+                 , yesod                         >= 1.4.1      && < 1.5                  , yesod-core                    >= 1.4.0      && < 1.5                  , yesod-auth                    >= 1.4.0      && < 1.5-                 , yesod-static                  >= 1.4.0      && < 1.5+                 , yesod-static                  >= 1.4.0.3    && < 1.5                  , yesod-form                    >= 1.4.0      && < 1.5+                 , classy-prelude                >= 0.10.2+                 , classy-prelude-conduit        >= 0.10.2+                 , classy-prelude-yesod          >= 0.10.2                  , bytestring                    >= 0.9        && < 0.11                  , text                          >= 0.11       && < 2.0                  , persistent                    >= 2.0        && < 2.2-                 , persistent-postgresql         >= 2.0        && < 2.2+                 , persistent-postgresql         >= 2.1.1      && < 2.2                  , persistent-template           >= 2.0        && < 2.2                  , template-haskell                  , shakespeare                   >= 2.0        && < 2.1@@ -452,10 +481,12 @@                  , monad-logger                  >= 0.3        && < 0.4                  , fast-logger                   >= 2.2        && < 2.3                  , wai-logger                    >= 2.2        && < 2.3--    -- see https://github.com/yesodweb/yesod/issues/814-    if !os(windows)-        build-depends: unix+                 , file-embed+                 , safe+                 , unordered-containers+                 , containers+                 , vector+                 , time  executable         PROJECTNAME     if flag(library-only)@@ -463,9 +494,7 @@      main-is:           main.hs     hs-source-dirs:    app-    build-depends:     base-                     , PROJECTNAME-                     , yesod+    build-depends:     base, PROJECTNAME      ghc-options:       -threaded -O2 -rtsopts -with-rtsopts=-N @@ -493,7 +522,7 @@      build-depends: base                  , PROJECTNAME-                 , yesod-test >= 1.4 && < 1.5+                 , yesod-test >= 1.4.2 && < 1.5                  , yesod-core                  , yesod                  , persistent@@ -502,6 +531,8 @@                  , monad-logger                  , transformers                  , hspec+                 , classy-prelude+                 , classy-prelude-yesod  {-# START_FILE Settings.hs #-} -- | Settings are centralized, as much as possible, into this file. This@@ -511,45 +542,81 @@ -- declared in the Foundation.hs file. module Settings where -import Prelude-import Text.Shakespeare.Text (st)-import Language.Haskell.TH.Syntax+import ClassyPrelude.Yesod+import Control.Exception           (throw)+import Data.Aeson                  (Result (..), fromJSON, withObject, (.!=),+                                    (.:?))+import Data.FileEmbed              (embedFile)+import Data.Yaml                   (decodeEither') import Database.Persist.Postgresql (PostgresConf)-import Yesod.Default.Config-import Yesod.Default.Util-import Data.Text (Text)-import Data.Yaml-import Control.Applicative-import Settings.Development-import Data.Default (def)-import Text.Hamlet+import Language.Haskell.TH.Syntax  (Exp, Name, Q)+import Network.Wai.Handler.Warp    (HostPreference)+import Yesod.Default.Config2       (applyEnvValue, configSettingsYml)+import Yesod.Default.Util          (WidgetFileSettings, widgetFileNoReload,+                                    widgetFileReload) --- | Which Persistent backend this site is using.-type PersistConf = PostgresConf+-- | Runtime settings to configure this application. These settings can be+-- loaded from various sources: defaults, environment variables, config files,+-- theoretically even a database.+data AppSettings = AppSettings+    { appStaticDir              :: String+    -- ^ Directory from which to serve static files.+    , appDatabaseConf           :: PostgresConf+    -- ^ Configuration settings for accessing the database.+    , appRoot                   :: Text+    -- ^ Base for all generated URLs.+    , appHost                   :: HostPreference+    -- ^ Host/interface the server should bind to.+    , appPort                   :: Int+    -- ^ Port to listen on+    , appIpFromHeader           :: Bool+    -- ^ Get the IP address from the header when logging. Useful when sitting+    -- behind a reverse proxy. --- Static setting below. Changing these requires a recompile+    , appDetailedRequestLogging :: Bool+    -- ^ Use detailed request logging system+    , appShouldLogAll           :: Bool+    -- ^ Should all log messages be displayed?+    , appReloadTemplates        :: Bool+    -- ^ Use the reload version of templates+    , appMutableStatic          :: Bool+    -- ^ Assume that files in the static dir may change after compilation+    , appSkipCombining          :: Bool+    -- ^ Perform no stylesheet/script combining --- | The location of static files on your system. This is a file system--- path. The default value works properly with your scaffolded site.-staticDir :: FilePath-staticDir = "static"+    -- Example app-specific configuration values.+    , appCopyright              :: Text+    -- ^ Copyright text to appear in the footer of the page+    , appAnalytics              :: Maybe Text+    -- ^ Google Analytics code+    } --- | The base URL for your static files. As you can see by the default--- value, this can simply be "static" appended to your application root.--- A powerful optimization can be serving static files from a separate--- domain name. This allows you to use a web server optimized for static--- files, more easily set expires and cache values, and avoid possibly--- costly transference of cookies on static files. For more information,--- please see:---   http://code.google.com/speed/page-speed/docs/request.html#ServeFromCookielessDomain------ If you change the resource pattern for StaticR in Foundation.hs, you will--- have to make a corresponding change here.------ To see how this value is used, see urlRenderOverride in Foundation.hs-staticRoot :: AppConfig DefaultEnv x -> Text-staticRoot conf = [st|#{appRoot conf}/static|]+instance FromJSON AppSettings where+    parseJSON = withObject "AppSettings" $ \o -> do+        let defaultDev =+#if DEVELOPMENT+                True+#else+                False+#endif+        appStaticDir              <- o .: "static-dir"+        appDatabaseConf           <- o .: "database"+        appRoot                   <- o .: "approot"+        appHost                   <- fromString <$> o .: "host"+        appPort                   <- o .: "port"+        appIpFromHeader           <- o .: "ip-from-header" +        appDetailedRequestLogging <- o .:? "detailed-logging" .!= defaultDev+        appShouldLogAll           <- o .:? "should-log-all"   .!= defaultDev+        appReloadTemplates        <- o .:? "reload-templates" .!= defaultDev+        appMutableStatic          <- o .:? "mutable-static"   .!= defaultDev+        appSkipCombining          <- o .:? "skip-combining"   .!= defaultDev++        appCopyright              <- o .: "copyright"+        appAnalytics              <- o .:? "analytics"++        return AppSettings {..}+ -- | Settings for 'widgetFile', such as which template languages to support and -- default Hamlet settings. --@@ -558,81 +625,62 @@ -- https://github.com/yesodweb/yesod/wiki/Overriding-widgetFile widgetFileSettings :: WidgetFileSettings widgetFileSettings = def-    { wfsHamletSettings = defaultHamletSettings-        { hamletNewlines = AlwaysNewlines-        }-    } +-- | How static files should be combined.+combineSettings :: CombineSettings+combineSettings = def+ -- The rest of this file contains settings which rarely need changing by a -- user.  widgetFile :: String -> Q Exp-widgetFile = (if development then widgetFileReload-                             else widgetFileNoReload)+widgetFile = (if appReloadTemplates compileTimeAppSettings+                then widgetFileReload+                else widgetFileNoReload)               widgetFileSettings -data Extra = Extra-    { extraCopyright :: Text-    , extraAnalytics :: Maybe Text -- ^ Google Analytics-    } deriving Show+-- | Raw bytes at compile time of @config/settings.yml@+configSettingsYmlBS :: ByteString+configSettingsYmlBS = $(embedFile configSettingsYml) -parseExtra :: DefaultEnv -> Object -> Parser Extra-parseExtra _ o = Extra-    <$> o .:  "copyright"-    <*> o .:? "analytics"+-- | @config/settings.yml@, parsed to a @Value@.+configSettingsYmlValue :: Value+configSettingsYmlValue = either throw id $ decodeEither' configSettingsYmlBS -{-# START_FILE Settings/Development.hs #-}-module Settings.Development where+-- | A version of @AppSettings@ parsed at compile time from @config/settings.yml@.+compileTimeAppSettings :: AppSettings+compileTimeAppSettings =+    case fromJSON $ applyEnvValue False mempty configSettingsYmlValue of+        Error e -> error e+        Success settings -> settings -import Prelude+-- The following two functions can be used to combine multiple CSS or JS files+-- at compile time to decrease the number of http requests.+-- Sample usage (inside a Widget):+--+-- > $(combineStylesheets 'StaticR [style1_css, style2_css]) -development :: Bool-development =-#if DEVELOPMENT-  True-#else-  False-#endif+combineStylesheets :: Name -> [Route Static] -> Q Exp+combineStylesheets = combineStylesheets'+    (appSkipCombining compileTimeAppSettings)+    combineSettings -production :: Bool-production = not development+combineScripts :: Name -> [Route Static] -> Q Exp+combineScripts = combineScripts'+    (appSkipCombining compileTimeAppSettings)+    combineSettings  {-# START_FILE Settings/StaticFiles.hs #-} module Settings.StaticFiles where -import Prelude (IO)-import Yesod.Static-import qualified Yesod.Static as Static-import Settings (staticDir)-import Settings.Development-import Language.Haskell.TH (Q, Exp, Name)-import Data.Default (def)---- | use this to create your static file serving site-staticSite :: IO Static.Static-staticSite = if development then Static.staticDevel staticDir-                            else Static.static      staticDir+import Settings     (appStaticDir, compileTimeAppSettings)+import Yesod.Static (staticFiles)  -- | This generates easy references to files in the static directory at compile time, --   giving you compile-time verification that referenced files exist. --   Warning: any files added to your static directory during run-time can't be --   accessed this way. You'll have to use their FilePath or URL to access them.-$(staticFiles Settings.staticDir)--combineSettings :: CombineSettings-combineSettings = def---- The following two functions can be used to combine multiple CSS or JS files--- at compile time to decrease the number of http requests.--- Sample usage (inside a Widget):------ > $(combineStylesheets 'StaticR [style1_css, style2_css])--combineStylesheets :: Name -> [Route Static] -> Q Exp-combineStylesheets = combineStylesheets' development combineSettings--combineScripts :: Name -> [Route Static] -> Q Exp-combineScripts = combineScripts' development combineSettings+staticFiles (appStaticDir compileTimeAppSettings)  {-# START_FILE app/DevelMain.hs #-} -- | Development version to be run inside GHCi.@@ -699,19 +747,24 @@ start :: MVar () -- ^ Written to when the thread is killed.       -> IO ThreadId start done = do-    (port,app) <- getApplicationDev-    forkIO (finally (runSettings (setPort port defaultSettings) app)+    (settings,app) <- getApplicationDev+    forkIO (finally (runSettings settings app)                     (putMVar done ())) +{-# START_FILE app/devel.hs #-}+{-# LANGUAGE PackageImports #-}+import "PROJECTNAME" Application (develMain)+import Prelude (IO)++main :: IO ()+main = develMain+ {-# START_FILE app/main.hs #-}-import Prelude              (IO)-import Yesod.Default.Config (fromArgs)-import Yesod.Default.Main   (defaultMainLog)-import Settings             (parseExtra)-import Application          (makeApplication)+import Prelude     (IO)+import Application (appMain)  main :: IO ()-main = defaultMainLog (fromArgs parseExtra) makeApplication+main = appMain  {-# START_FILE BASE64 config/favicon.ico #-} AAABAAIAEBAAAAEAIABoBAAAJgAAABAQAgABAAEAsAAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAA@@ -816,46 +869,11 @@   -- By default this file is used in Model.hs (which is imported by Foundation.hs) -{-# START_FILE config/postgresql.yml #-}-# NOTE: These settings can be overridden by environment variables as well, in-# particular:-#-#    PGHOST-#    PGPORT-#    PGUSER-#    PGPASS-#    PGDATABASE--Default: &defaults-  user: PROJECTNAME-  password: PROJECTNAME-  host: localhost-  port: 5432-  database: PROJECTNAME-  poolsize: 10--Development:-  <<: *defaults--Testing:-  database: PROJECTNAME_test-  <<: *defaults--Staging:-  database: PROJECTNAME_staging-  poolsize: 100-  <<: *defaults--Production:-  database: PROJECTNAME_production-  poolsize: 100-  <<: *defaults- {-# START_FILE config/robots.txt #-} User-agent: *  {-# START_FILE config/routes #-}-/static StaticR Static getStatic+/static StaticR Static appStatic /auth   AuthR   Auth   getAuth  /favicon.ico FaviconR GET@@ -864,155 +882,36 @@ / HomeR GET POST  {-# START_FILE config/settings.yml #-}-Default: &defaults-  host: "*4" # any IPv4 host-  port: 3000-  approot: "http://localhost:3000"-  copyright: Insert copyright statement here-  #analytics: UA-YOURCODE--Development:-  <<: *defaults--Testing:-  <<: *defaults--Staging:-  <<: *defaults--Production:-  #approot: "http://www.example.com"-  <<: *defaults--{-# START_FILE deploy/Procfile #-}-# Free deployment to Heroku.-#-#   !! Warning: You must use a 64 bit machine to compile !!-#-#   This could mean using a virtual machine. Give your VM as much memory as you can to speed up linking.-#-# Basic Yesod setup:-#-# * Move this file out of the deploy directory and into your root directory-#-#     mv deploy/Procfile ./-#-# * Create an empty package.json-#     echo '{ "name": "PROJECTNAME", "version": "0.0.1", "dependencies": {} }' >> package.json-#-# Postgresql Yesod setup:-#-# * add dependencies on the "heroku", "aeson" and "unordered-containers" packages in your cabal file-#-# * add code in Application.hs to use the heroku package and load the connection parameters.-#   The below works for Postgresql.-#-#   import Data.HashMap.Strict as H-#   import Data.Aeson.Types as AT-#   #ifndef DEVELOPMENT-#   import qualified Web.Heroku-#   #endif-#-#-#-#   makeFoundation :: AppConfig DefaultEnv Extra -> Logger -> IO App-#   makeFoundation conf setLogger = do-#       manager <- newManager def-#       s <- staticSite-#       hconfig <- loadHerokuConfig-#       dbconf <- withYamlEnvironment "config/postgresql.yml" (appEnv conf)-#                 (Database.Persist.Store.loadConfig . combineMappings hconfig) >>=-#                 Database.Persist.Store.applyEnv-#       p <- Database.Persist.Store.createPoolConfig (dbconf :: Settings.PersistConfig)-#       Database.Persist.Store.runPool dbconf (runMigration migrateAll) p-#       return $ App conf setLogger s p manager dbconf-#-#   #ifndef DEVELOPMENT-#   canonicalizeKey :: (Text, val) -> (Text, val)-#   canonicalizeKey ("dbname", val) = ("database", val)-#   canonicalizeKey pair = pair-#-#   toMapping :: [(Text, Text)] -> AT.Value-#   toMapping xs = AT.Object $ M.fromList $ map (\(key, val) -> (key, AT.String val)) xs-#   #endif-#-#   combineMappings :: AT.Value -> AT.Value -> AT.Value-#   combineMappings (AT.Object m1) (AT.Object m2) = AT.Object $ m1 `M.union` m2-#   combineMappings _ _ = error "Data.Object is not a Mapping."-#-#   loadHerokuConfig :: IO AT.Value-#   loadHerokuConfig = do-#   #ifdef DEVELOPMENT-#       return $ AT.Object M.empty-#   #else-#       Web.Heroku.dbConnParams >>= return . toMapping . map canonicalizeKey-#   #endif--+static-dir:     "_env:STATIC_DIR:static"+host:           "_env:HOST:*4" # any IPv4 host+port:           "_env:PORT:3000"+approot:        "_env:APPROOT:http://localhost:3000"+ip-from-header: "_env:IP_FROM_HEADER:false" -# Heroku setup:-# Find the Heroku guide. Roughly:-#-# * sign up for a heroku account and register your ssh key-# * create a new application on the *cedar* stack-#-# * make your Yesod project the git repository for that application-# * create a deploy branch-#-#     git checkout -b deploy-#-# Repeat these steps to deploy:-# * add your web executable binary (referenced below) to the git repository-#-#     git checkout deploy-#     git add ./dist/build/PROJECTNAME/PROJECTNAME-#     git commit -m deploy-#-# * push to Heroku+# Optional values with the following production defaults.+# In development, they default to the inverse. #-#     git push heroku deploy:master---# Heroku configuration that runs your app-web: ./dist/build/PROJECTNAME/PROJECTNAME production -p $PORT--{-# START_FILE devel.hs #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE PackageImports #-}-import "PROJECTNAME" Application (getApplicationDev)-import Network.Wai.Handler.Warp-    (runSettings, defaultSettings, setPort)-import Control.Concurrent (forkIO)-import System.Directory (doesFileExist, removeFile)-import System.Exit (exitSuccess)-import Control.Concurrent (threadDelay)--#ifndef mingw32_HOST_OS-import System.Posix.Signals (installHandler, sigINT, Handler(Catch))-#endif--main :: IO ()-main = do-#ifndef mingw32_HOST_OS-    _ <- installHandler sigINT (Catch $ return ()) Nothing-#endif--    putStrLn "Starting devel application"-    (port, app) <- getApplicationDev-    forkIO $ runSettings (setPort port defaultSettings) app-    loop+# development: false+# detailed-logging: false+# should-log-all: false+# reload-templates: false+# mutable-static: false+# skip-combining: false -loop :: IO ()-loop = do-  threadDelay 100000-  e <- doesFileExist "yesod-devel/devel-terminate"-  if e then terminateDevel else loop+database:+  user:     "_env:PGUSER:PROJECTNAME"+  password: "_env:PGPASS:PROJECTNAME"+  host:     "_env:PGHOST:localhost"+  port:     "_env:PGPORT:5432"+  database: "_env:PGDATABASE:PROJECTNAME"+  poolsize: "_env:PGPOOLSIZE:10" -terminateDevel :: IO ()-terminateDevel = exitSuccess+copyright: Insert copyright statement here+#analytics: UA-YOURCODE -{-# START_FILE messages/en.msg #-}-Hello: Hello+{-# START_FILE config/test-settings.yml #-}+database:+  database: PROJECTNAME_test  {-# START_FILE static/css/bootstrap.css #-} /*!@@ -8978,9 +8877,9 @@             <div id="main" role="main">               ^{pageBody pc}             <footer>-                #{extraCopyright $ appExtra $ settings master}+                #{appCopyright $ appSettings master} -        $maybe analytics <- extraAnalytics $ appExtra $ settings master+        $maybe analytics <- appAnalytics $ appSettings master             <script>               if(!window.location.href.match(/localhost/)){                 window._gaq = [['_setAccount','#{analytics}'],['_trackPageview'],['_trackPageLoadTime']];@@ -9003,7 +8902,7 @@ ^{widget}  {-# START_FILE templates/homepage.hamlet #-}-<h1>_{MsgHello}+<h1>Welcome to Yesod!  <ol>   <li>Now that you have a working project you should use the #@@ -9054,92 +8953,88 @@     color: #990 } -{-# START_FILE test/Handler/HomeSpec.hs #-}-module Handler.HomeSpec-    ( spec-    ) where+{-# START_FILE test/Handler/CommonSpec.hs #-}+module Handler.CommonSpec (spec) where  import TestImport-import qualified Data.List as L  spec :: Spec-spec =-    ydescribe "These are some example tests" $ do--        yit "loads the index and checks it looks right" $ do-            get HomeR+spec = withApp $ do+    describe "robots.txt" $ do+        it "gives a 200" $ do+            get RobotsR             statusIs 200-            htmlAllContain "h1" "Hello"+        it "has correct User-agent" $ do+            get RobotsR+            bodyContains "User-agent: *"+    describe "favicon.ico" $ do+        it "gives a 200" $ do+            get FaviconR+            statusIs 200 -            request $ do-                setMethod "POST"-                setUrl HomeR-                addNonce-                fileByLabel "Choose a file" "test/Spec.hs" "text/plain" -- talk about self-reference-                byLabel "What's on the file?" "Some Content"+{-# START_FILE test/Handler/HomeSpec.hs #-}+module Handler.HomeSpec (spec) where -            statusIs 200-            -- more debugging printBody-            htmlCount ".message" 1-            htmlAllContain ".message" "Some Content"-            htmlAllContain ".message" "text/plain"+import TestImport -        -- This is a simple example of using a database access in a test.  The-        -- test will succeed for a fresh scaffolded site with an empty database,-        -- but will fail on an existing database with a non-empty user table.-        yit "leaves the user table empty" $ do-            get HomeR-            statusIs 200-            users <- runDB $ selectList ([] :: [Filter User]) []-            assertEqual "user table empty" 0 $ L.length users+spec :: Spec+spec = withApp $ do+    it "loads the index and checks it looks right" $ do+        get HomeR+        statusIs 200+        htmlAllContain "h1" "Welcome to Yesod" -{-# START_FILE test/Spec.hs #-}-module Main where+        request $ do+            setMethod "POST"+            setUrl HomeR+            addNonce+            fileByLabel "Choose a file" "test/Spec.hs" "text/plain" -- talk about self-reference+            byLabel "What's on the file?" "Some Content" -import Import-import Yesod.Default.Config-import Yesod.Test-import Test.Hspec (hspec)-import Application (makeFoundation)+        statusIs 200+        -- more debugging printBody+        htmlCount ".message" 1+        htmlAllContain ".message" "Some Content"+        htmlAllContain ".message" "text/plain" -import qualified Handler.HomeSpec+    -- This is a simple example of using a database access in a test.  The+    -- test will succeed for a fresh scaffolded site with an empty database,+    -- but will fail on an existing database with a non-empty user table.+    it "leaves the user table empty" $ do+        get HomeR+        statusIs 200+        users <- runDB $ selectList ([] :: [Filter User]) []+        assertEqual "user table empty" 0 $ length users -main :: IO ()-main = do-    conf <- Yesod.Default.Config.loadConfig $ (configSettings Testing)-                { csParseExtra = parseExtra-                }-    foundation <- makeFoundation conf-    hspec $ do-        yesodSpec foundation $ do-            Handler.HomeSpec.spec+{-# START_FILE test/Spec.hs #-}+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}  {-# START_FILE test/TestImport.hs #-} module TestImport-    ( module Yesod.Test-    , module Model-    , module Foundation-    , module Database.Persist-    , module Prelude-    , runDB-    , Spec-    , Example+    ( module TestImport+    , module X     ) where -import Yesod.Test-import Database.Persist hiding (get)-import Database.Persist.Sql (SqlPersistM, runSqlPersistMPool)-import Control.Monad.IO.Class (liftIO)-import Prelude--import Foundation-import Model--type Spec = YesodSpec App-type Example = YesodExample App+import Application           (makeFoundation)+import ClassyPrelude         as X+import Database.Persist      as X hiding (get)+import Database.Persist.Sql  (SqlPersistM, runSqlPersistMPool)+import Foundation            as X+import Model                 as X+import Test.Hspec            as X+import Yesod.Default.Config2 (ignoreEnv, loadAppSettings)+import Yesod.Test            as X -runDB :: SqlPersistM a -> Example a+runDB :: SqlPersistM a -> YesodExample App a runDB query = do-    pool <- fmap connPool getTestYesod+    pool <- fmap appConnPool getTestYesod     liftIO $ runSqlPersistMPool query pool++withApp :: SpecWith App -> Spec+withApp = before $ do+    settings <- loadAppSettings+        ["config/test-settings.yml", "config/settings.yml"]+        []+        ignoreEnv+    makeFoundation settings 
hsfiles/simple.hsfiles view
@@ -28,27 +28,29 @@ {-# START_FILE Application.hs #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Application-    ( makeApplication-    , getApplicationDev+    ( getApplicationDev+    , appMain+    , develMain     , makeFoundation     ) where +import Control.Monad.Logger                 (liftLoc) import Import-import Yesod.Default.Config-import Yesod.Default.Main-import Yesod.Default.Handlers-import Network.Wai.Middleware.RequestLogger-    ( mkRequestLogger, outputFormat, OutputFormat (..), IPAddrSource (..), destination-    )-import qualified Network.Wai.Middleware.RequestLogger as RequestLogger-import Network.HTTP.Client.Conduit (newManager)-import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize)-import Network.Wai.Logger (clockDateCacher)-import Data.Default (def)-import Yesod.Core.Types (loggerSet, Logger (Logger))+import Language.Haskell.TH.Syntax           (qLocation)+import Network.Wai.Handler.Warp             (Settings, defaultSettings,+                                             defaultShouldDisplayException,+                                             runSettings, setHost,+                                             setOnException, setPort)+import Network.Wai.Middleware.RequestLogger (Destination (Logger),+                                             IPAddrSource (..),+                                             OutputFormat (..), destination,+                                             mkRequestLogger, outputFormat)+import System.Log.FastLogger                (defaultBufSize, newStdoutLoggerSet,+                                             toLogStr)  -- Import all relevant handler modules here. -- Don't forget to add new modules to your cabal file!+import Handler.Common import Handler.Home  -- This line actually creates our YesodDispatch instance. It is the second half@@ -56,90 +58,114 @@ -- 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+-- | This function allocates resources (such as a database connection pool),+-- performs initialization and return a foundation datatype value. This is also+-- the place to put your migrate statements to have automatic database -- migrations handled by Yesod.-makeApplication :: AppConfig DefaultEnv Extra -> IO (Application, LogFunc)-makeApplication conf = do-    foundation <- makeFoundation conf+makeFoundation :: AppSettings -> IO App+makeFoundation appSettings = do+    -- Some basic initializations: HTTP connection manager, logger, and static+    -- subsite.+    appHttpManager <- newManager+    appLogger <- newStdoutLoggerSet defaultBufSize >>= makeYesodLogger+    appStatic <-+        (if appMutableStatic appSettings then staticDevel else static)+        (appStaticDir appSettings) -    -- Initialize the logging middleware+    -- Return the foundation+    return App {..}++-- | Convert our foundation to a WAI Application by calling @toWaiAppPlain@ and+-- applyng some additional middlewares.+makeApplication :: App -> IO Application+makeApplication foundation = do     logWare <- mkRequestLogger def         { outputFormat =-            if development+            if appDetailedRequestLogging $ appSettings foundation                 then Detailed True-                else Apache FromSocket-        , destination = RequestLogger.Logger $ loggerSet $ appLogger foundation+                else Apache+                        (if appIpFromHeader $ appSettings foundation+                            then FromFallback+                            else FromSocket)+        , destination = Logger $ loggerSet $ appLogger foundation         }      -- Create the WAI application and apply middlewares-    app <- toWaiAppPlain foundation-    let logFunc = messageLoggerSource foundation (appLogger foundation)-    return (logWare $ defaultMiddlewaresNoLogging app, logFunc)+    appPlain <- toWaiAppPlain foundation+    return $ logWare $ defaultMiddlewaresNoLogging appPlain --- | Loads up any necessary settings, creates your foundation datatype, and--- performs some initialization.-makeFoundation :: AppConfig DefaultEnv Extra -> IO App-makeFoundation conf = do-    manager <- newManager-    s <- staticSite+-- | Warp settings for the given foundation value.+warpSettings :: App -> Settings+warpSettings foundation =+      setPort (appPort $ appSettings foundation)+    $ setHost (appHost $ appSettings foundation)+    $ setOnException (\_req e ->+        when (defaultShouldDisplayException e) $ messageLoggerSource+            foundation+            (appLogger foundation)+            $(qLocation >>= liftLoc)+            "yesod"+            LevelError+            (toLogStr $ "Exception from Warp: " ++ show e))+      defaultSettings -    loggerSet' <- newStdoutLoggerSet defaultBufSize-    (getter, _) <- clockDateCacher+-- | For yesod devel, return the Warp settings and WAI Application.+getApplicationDev :: IO (Settings, Application)+getApplicationDev = do+    settings <- loadAppSettings [configSettingsYml] [] useEnv+    foundation <- makeFoundation settings+    app <- makeApplication foundation+    wsettings <- getDevSettings $ warpSettings foundation+    return (wsettings, app) -    let logger = Yesod.Core.Types.Logger loggerSet' getter-        foundation = App-            { settings = conf-            , getStatic = s-            , httpManager = manager-            , appLogger = logger-            }+-- | main function for use by yesod devel+develMain :: IO ()+develMain = develMainHelper getApplicationDev -    return foundation+-- | The @main@ function for an executable running this site.+appMain :: IO ()+appMain = do+    -- Get the settings from all relevant sources+    settings <- loadAppSettingsArgs+        -- fall back to compile-time values, set to [] to require values at runtime+        [configSettingsYmlValue] --- for yesod devel-getApplicationDev :: IO (Int, Application)-getApplicationDev =-    defaultDevelApp loader (fmap fst . makeApplication)-  where-    loader = Yesod.Default.Config.loadConfig (configSettings Development)-        { csParseExtra = parseExtra-        }+        -- allow environment variables to override+        useEnv +    -- Generate the foundation from the settings+    foundation <- makeFoundation settings++    -- Generate a WAI Application from the foundation+    app <- makeApplication foundation++    -- Run the application with Warp+    runSettings (warpSettings foundation) app+ {-# START_FILE Foundation.hs #-} module Foundation where -import Prelude-import Yesod-import Yesod.Static-import Yesod.Default.Config-import Yesod.Default.Util (addStaticContentExternal)-import Network.HTTP.Client.Conduit (Manager, HasHttpManager (getHttpManager))-import qualified Settings-import Settings.Development (development)+import ClassyPrelude.Yesod+import Settings import Settings.StaticFiles-import Settings (widgetFile, Extra (..))-import Text.Jasmine (minifym)-import Text.Hamlet (hamletFile)-import Yesod.Core.Types (Logger)+import Text.Hamlet          (hamletFile)+import Text.Jasmine         (minifym)+import Yesod.Core.Types     (Logger)+import Yesod.Default.Util   (addStaticContentExternal) --- | The site argument for your application. This can be a good place to+-- | The foundation datatype 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-    , appLogger :: Logger+    { appSettings    :: AppSettings+    , appStatic      :: Static -- ^ Settings for static file serving.+    , appHttpManager :: Manager+    , appLogger      :: Logger     }  instance HasHttpManager App where-    getHttpManager = httpManager---- Set up i18n messages. See the message folder.-mkMessage "App" "messages" "en"+    getHttpManager = appHttpManager  -- This is where we define all of the routes in our application. For a full -- explanation of the syntax, please see:@@ -150,12 +176,15 @@ -- explanation for this split. mkYesodData "App" $(parseRoutesFile "config/routes") +-- | A convenient synonym for creating forms. type Form x = Html -> MForm (HandlerT App IO) (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+    -- Controls the base of generated URLs. For more information on modifying,+    -- see: https://github.com/yesodweb/yesod/wiki/Overriding-approot+    approot = ApprootMaster $ appRoot . appSettings      -- Store session data on the client in encrypted cookies,     -- default session idle timeout is 120 minutes@@ -178,12 +207,6 @@             $(widgetFile "default-layout")         withUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet") -    -- This is done to provide an optimization for serving static files from-    -- a separate domain. Please see the staticRoot setting in Settings.hs-    urlRenderOverride y (StaticR s) =-        Just $ uncurry (joinPath y (Settings.staticRoot $ settings y)) $ renderRoute s-    urlRenderOverride _ _ = Nothing-     -- Routes not requiring authenitcation.     isAuthorized FaviconR _ = return Authorized     isAuthorized RobotsR _ = return Authorized@@ -194,21 +217,27 @@     -- and names them based on a hash of their content. This allows     -- expiration dates to be set far in the future without worry of     -- users receiving stale content.-    addStaticContent =-        addStaticContentExternal minifym genFileName Settings.staticDir (StaticR . flip StaticRoute [])+    addStaticContent ext mime content = do+        master <- getYesod+        let staticDir = appStaticDir $ appSettings master+        addStaticContentExternal+            minifym+            genFileName+            staticDir+            (StaticR . flip StaticRoute [])+            ext+            mime+            content       where         -- Generate a unique filename based on the content itself-        genFileName lbs-            | development = "autogen-" ++ base64md5 lbs-            | otherwise   = base64md5 lbs--    -- Place Javascript at bottom of the body tag so the rest of the page loads first-    jsLoader _ = BottomOfBody+        genFileName lbs = "autogen-" ++ base64md5 lbs      -- What messages should be logged. The following includes all messages when     -- in development, and warnings and errors in production.-    shouldLog _ _source level =-        development || level == LevelWarn || level == LevelError+    shouldLog app _source level =+        appShouldLogAll (appSettings app)+            || level == LevelWarn+            || level == LevelError      makeLogger = return . appLogger @@ -217,23 +246,38 @@ instance RenderMessage App FormMessage where     renderMessage _ _ = defaultFormMessage --- | Get the 'Extra' value, used to hold data from the settings.yml file.-getExtra :: Handler Extra-getExtra = fmap (appExtra . settings) getYesod---- Note: previous versions of the scaffolding included a deliver function to--- send emails. Unfortunately, there are too many different options for us to--- give a reasonable default. Instead, the information is available on the--- wiki:+-- Note: Some functionality previously present in the scaffolding has been+-- moved to documentation in the Wiki. Following are some hopefully helpful+-- links: -- -- https://github.com/yesodweb/yesod/wiki/Sending-email+-- https://github.com/yesodweb/yesod/wiki/Serve-static-files-from-a-separate-domain+-- https://github.com/yesodweb/yesod/wiki/i18n-messages-in-the-scaffolding +{-# START_FILE Handler/Common.hs #-}+-- | Common handler functions.+module Handler.Common where++import Data.FileEmbed (embedFile)+import Import++-- These handlers embed files in the executable at compile time to avoid a+-- runtime dependency, and for efficiency.++getFaviconR :: Handler TypedContent+getFaviconR = return $ TypedContent "image/x-icon"+                     $ toContent $(embedFile "config/favicon.ico")++getRobotsR :: Handler TypedContent+getRobotsR = return $ TypedContent typePlain+                    $ toContent $(embedFile "config/robots.txt")+ {-# START_FILE Handler/Home.hs #-} module Handler.Home where  import Import-import Yesod.Form.Bootstrap3-    ( BootstrapFormLayout (..), renderBootstrap3, withSmallInput )+import Yesod.Form.Bootstrap3 (BootstrapFormLayout (..), renderBootstrap3,+                              withSmallInput)  -- This is a handler function for the GET request method on the HomeR -- resource pattern. All of your resource patterns are defined in@@ -275,30 +319,12 @@     ( module Import     ) where -import           Prelude              as Import hiding (head, init, last,-                                                 readFile, tail, writeFile)-import           Yesod                as Import hiding (Route (..))--import           Control.Applicative  as Import (pure, (<$>), (<*>))-import           Data.Text            as Import (Text)--import           Foundation           as Import-import           Settings             as Import-import           Settings.Development as Import-import           Settings.StaticFiles as Import--#if __GLASGOW_HASKELL__ >= 704-import           Data.Monoid          as Import-                                                 (Monoid (mappend, mempty, mconcat),-                                                 (<>))-#else-import           Data.Monoid          as Import-                                                 (Monoid (mappend, mempty, mconcat))--infixr 5 <>-(<>) :: Monoid m => m -> m -> m-(<>) = mappend-#endif+import ClassyPrelude.Yesod   as Import+import Foundation            as Import+import Settings              as Import+import Settings.StaticFiles  as Import+import Yesod.Core.Types      as Import (loggerSet)+import Yesod.Default.Config2 as Import  {-# START_FILE PROJECTNAME.cabal #-} name:              PROJECTNAME@@ -320,7 +346,7 @@                      Import                      Settings                      Settings.StaticFiles-                     Settings.Development+                     Handler.Common                      Handler.Home      if flag(dev) || flag(library-only)@@ -344,13 +370,17 @@                 DeriveDataTypeable                 ViewPatterns                 TupleSections+                RecordWildCards      build-depends: base                          >= 4          && < 5-                 , yesod                         >= 1.4.0      && < 1.5+                 , yesod                         >= 1.4.1      && < 1.5                  , yesod-core                    >= 1.4.0      && < 1.5                  , yesod-auth                    >= 1.4.0      && < 1.5-                 , yesod-static                  >= 1.4.0      && < 1.5+                 , yesod-static                  >= 1.4.0.3    && < 1.5                  , yesod-form                    >= 1.4.0      && < 1.5+                 , classy-prelude                >= 0.10.2+                 , classy-prelude-conduit        >= 0.10.2+                 , classy-prelude-yesod          >= 0.10.2                  , bytestring                    >= 0.9        && < 0.11                  , text                          >= 0.11       && < 2.0                  , template-haskell@@ -368,10 +398,12 @@                  , monad-logger                  >= 0.3        && < 0.4                  , fast-logger                   >= 2.2        && < 2.3                  , wai-logger                    >= 2.2        && < 2.3--    -- see https://github.com/yesodweb/yesod/issues/814-    if !os(windows)-        build-depends: unix+                 , file-embed+                 , safe+                 , unordered-containers+                 , containers+                 , vector+                 , time  executable         PROJECTNAME     if flag(library-only)@@ -379,9 +411,7 @@      main-is:           main.hs     hs-source-dirs:    app-    build-depends:     base-                     , PROJECTNAME-                     , yesod+    build-depends:     base, PROJECTNAME      ghc-options:       -threaded -O2 -rtsopts -with-rtsopts=-N @@ -409,10 +439,12 @@      build-depends: base                  , PROJECTNAME-                 , yesod-test >= 1.4 && < 1.5+                 , yesod-test >= 1.4.2 && < 1.5                  , yesod-core                  , yesod                  , hspec+                 , classy-prelude+                 , classy-prelude-yesod  {-# START_FILE Settings.hs #-} -- | Settings are centralized, as much as possible, into this file. This@@ -422,41 +454,77 @@ -- declared in the Foundation.hs file. module Settings where -import Prelude-import Text.Shakespeare.Text (st)-import Language.Haskell.TH.Syntax-import Yesod.Default.Config-import Yesod.Default.Util-import Data.Text (Text)-import Data.Yaml-import Control.Applicative-import Settings.Development-import Data.Default (def)-import Text.Hamlet+import ClassyPrelude.Yesod+import Control.Exception           (throw)+import Data.Aeson                  (Result (..), fromJSON, withObject, (.!=),+                                    (.:?))+import Data.FileEmbed              (embedFile)+import Data.Yaml                   (decodeEither')+import Language.Haskell.TH.Syntax  (Exp, Name, Q)+import Network.Wai.Handler.Warp    (HostPreference)+import Yesod.Default.Config2       (applyEnvValue, configSettingsYml)+import Yesod.Default.Util          (WidgetFileSettings, widgetFileNoReload,+                                    widgetFileReload) --- Static setting below. Changing these requires a recompile+-- | Runtime settings to configure this application. These settings can be+-- loaded from various sources: defaults, environment variables, config files,+-- theoretically even a database.+data AppSettings = AppSettings+    { appStaticDir              :: String+    -- ^ Directory from which to serve static files.+    , appRoot                   :: Text+    -- ^ Base for all generated URLs.+    , appHost                   :: HostPreference+    -- ^ Host/interface the server should bind to.+    , appPort                   :: Int+    -- ^ Port to listen on+    , appIpFromHeader           :: Bool+    -- ^ Get the IP address from the header when logging. Useful when sitting+    -- behind a reverse proxy. --- | The location of static files on your system. This is a file system--- path. The default value works properly with your scaffolded site.-staticDir :: FilePath-staticDir = "static"+    , appDetailedRequestLogging :: Bool+    -- ^ Use detailed request logging system+    , appShouldLogAll           :: Bool+    -- ^ Should all log messages be displayed?+    , appReloadTemplates        :: Bool+    -- ^ Use the reload version of templates+    , appMutableStatic          :: Bool+    -- ^ Assume that files in the static dir may change after compilation+    , appSkipCombining          :: Bool+    -- ^ Perform no stylesheet/script combining --- | The base URL for your static files. As you can see by the default--- value, this can simply be "static" appended to your application root.--- A powerful optimization can be serving static files from a separate--- domain name. This allows you to use a web server optimized for static--- files, more easily set expires and cache values, and avoid possibly--- costly transference of cookies on static files. For more information,--- please see:---   http://code.google.com/speed/page-speed/docs/request.html#ServeFromCookielessDomain------ If you change the resource pattern for StaticR in Foundation.hs, you will--- have to make a corresponding change here.------ To see how this value is used, see urlRenderOverride in Foundation.hs-staticRoot :: AppConfig DefaultEnv x -> Text-staticRoot conf = [st|#{appRoot conf}/static|]+    -- Example app-specific configuration values.+    , appCopyright              :: Text+    -- ^ Copyright text to appear in the footer of the page+    , appAnalytics              :: Maybe Text+    -- ^ Google Analytics code+    } +instance FromJSON AppSettings where+    parseJSON = withObject "AppSettings" $ \o -> do+        let defaultDev =+#if DEVELOPMENT+                True+#else+                False+#endif+        appStaticDir              <- o .: "static-dir"+        appRoot                   <- o .: "approot"+        appHost                   <- fromString <$> o .: "host"+        appPort                   <- o .: "port"+        appIpFromHeader           <- o .: "ip-from-header"++        appDetailedRequestLogging <- o .:? "detailed-logging" .!= defaultDev+        appShouldLogAll           <- o .:? "should-log-all"   .!= defaultDev+        appReloadTemplates        <- o .:? "reload-templates" .!= defaultDev+        appMutableStatic          <- o .:? "mutable-static"   .!= defaultDev+        appSkipCombining          <- o .:? "skip-combining"   .!= defaultDev++        appCopyright              <- o .: "copyright"+        appAnalytics              <- o .:? "analytics"++        return AppSettings {..}+ -- | Settings for 'widgetFile', such as which template languages to support and -- default Hamlet settings. --@@ -465,81 +533,62 @@ -- https://github.com/yesodweb/yesod/wiki/Overriding-widgetFile widgetFileSettings :: WidgetFileSettings widgetFileSettings = def-    { wfsHamletSettings = defaultHamletSettings-        { hamletNewlines = AlwaysNewlines-        }-    } +-- | How static files should be combined.+combineSettings :: CombineSettings+combineSettings = def+ -- The rest of this file contains settings which rarely need changing by a -- user.  widgetFile :: String -> Q Exp-widgetFile = (if development then widgetFileReload-                             else widgetFileNoReload)+widgetFile = (if appReloadTemplates compileTimeAppSettings+                then widgetFileReload+                else widgetFileNoReload)               widgetFileSettings -data Extra = Extra-    { extraCopyright :: Text-    , extraAnalytics :: Maybe Text -- ^ Google Analytics-    } deriving Show+-- | Raw bytes at compile time of @config/settings.yml@+configSettingsYmlBS :: ByteString+configSettingsYmlBS = $(embedFile configSettingsYml) -parseExtra :: DefaultEnv -> Object -> Parser Extra-parseExtra _ o = Extra-    <$> o .:  "copyright"-    <*> o .:? "analytics"+-- | @config/settings.yml@, parsed to a @Value@.+configSettingsYmlValue :: Value+configSettingsYmlValue = either throw id $ decodeEither' configSettingsYmlBS -{-# START_FILE Settings/Development.hs #-}-module Settings.Development where+-- | A version of @AppSettings@ parsed at compile time from @config/settings.yml@.+compileTimeAppSettings :: AppSettings+compileTimeAppSettings =+    case fromJSON $ applyEnvValue False mempty configSettingsYmlValue of+        Error e -> error e+        Success settings -> settings -import Prelude+-- The following two functions can be used to combine multiple CSS or JS files+-- at compile time to decrease the number of http requests.+-- Sample usage (inside a Widget):+--+-- > $(combineStylesheets 'StaticR [style1_css, style2_css]) -development :: Bool-development =-#if DEVELOPMENT-  True-#else-  False-#endif+combineStylesheets :: Name -> [Route Static] -> Q Exp+combineStylesheets = combineStylesheets'+    (appSkipCombining compileTimeAppSettings)+    combineSettings -production :: Bool-production = not development+combineScripts :: Name -> [Route Static] -> Q Exp+combineScripts = combineScripts'+    (appSkipCombining compileTimeAppSettings)+    combineSettings  {-# START_FILE Settings/StaticFiles.hs #-} module Settings.StaticFiles where -import Prelude (IO)-import Yesod.Static-import qualified Yesod.Static as Static-import Settings (staticDir)-import Settings.Development-import Language.Haskell.TH (Q, Exp, Name)-import Data.Default (def)---- | use this to create your static file serving site-staticSite :: IO Static.Static-staticSite = if development then Static.staticDevel staticDir-                            else Static.static      staticDir+import Settings     (appStaticDir, compileTimeAppSettings)+import Yesod.Static (staticFiles)  -- | This generates easy references to files in the static directory at compile time, --   giving you compile-time verification that referenced files exist. --   Warning: any files added to your static directory during run-time can't be --   accessed this way. You'll have to use their FilePath or URL to access them.-$(staticFiles Settings.staticDir)--combineSettings :: CombineSettings-combineSettings = def---- The following two functions can be used to combine multiple CSS or JS files--- at compile time to decrease the number of http requests.--- Sample usage (inside a Widget):------ > $(combineStylesheets 'StaticR [style1_css, style2_css])--combineStylesheets :: Name -> [Route Static] -> Q Exp-combineStylesheets = combineStylesheets' development combineSettings--combineScripts :: Name -> [Route Static] -> Q Exp-combineScripts = combineScripts' development combineSettings+staticFiles (appStaticDir compileTimeAppSettings)  {-# START_FILE app/DevelMain.hs #-} -- | Development version to be run inside GHCi.@@ -606,19 +655,24 @@ start :: MVar () -- ^ Written to when the thread is killed.       -> IO ThreadId start done = do-    (port,app) <- getApplicationDev-    forkIO (finally (runSettings (setPort port defaultSettings) app)+    (settings,app) <- getApplicationDev+    forkIO (finally (runSettings settings app)                     (putMVar done ())) +{-# START_FILE app/devel.hs #-}+{-# LANGUAGE PackageImports #-}+import "PROJECTNAME" Application (develMain)+import Prelude (IO)++main :: IO ()+main = develMain+ {-# START_FILE app/main.hs #-}-import Prelude              (IO)-import Yesod.Default.Config (fromArgs)-import Yesod.Default.Main   (defaultMainLog)-import Settings             (parseExtra)-import Application          (makeApplication)+import Prelude     (IO)+import Application (appMain)  main :: IO ()-main = defaultMainLog (fromArgs parseExtra) makeApplication+main = appMain  {-# START_FILE BASE64 config/favicon.ico #-} AAABAAIAEBAAAAEAIABoBAAAJgAAABAQAgABAAEAsAAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAA@@ -713,7 +767,7 @@ User-agent: *  {-# START_FILE config/routes #-}-/static StaticR Static getStatic+/static StaticR Static appStatic  /favicon.ico FaviconR GET /robots.txt RobotsR GET@@ -721,155 +775,28 @@ / HomeR GET POST  {-# START_FILE config/settings.yml #-}-Default: &defaults-  host: "*4" # any IPv4 host-  port: 3000-  approot: "http://localhost:3000"-  copyright: Insert copyright statement here-  #analytics: UA-YOURCODE--Development:-  <<: *defaults--Testing:-  <<: *defaults--Staging:-  <<: *defaults--Production:-  #approot: "http://www.example.com"-  <<: *defaults--{-# START_FILE deploy/Procfile #-}-# Free deployment to Heroku.-#-#   !! Warning: You must use a 64 bit machine to compile !!-#-#   This could mean using a virtual machine. Give your VM as much memory as you can to speed up linking.-#-# Basic Yesod setup:-#-# * Move this file out of the deploy directory and into your root directory-#-#     mv deploy/Procfile ./-#-# * Create an empty package.json-#     echo '{ "name": "PROJECTNAME", "version": "0.0.1", "dependencies": {} }' >> package.json-#-# Postgresql Yesod setup:-#-# * add dependencies on the "heroku", "aeson" and "unordered-containers" packages in your cabal file-#-# * add code in Application.hs to use the heroku package and load the connection parameters.-#   The below works for Postgresql.-#-#   import Data.HashMap.Strict as H-#   import Data.Aeson.Types as AT-#   #ifndef DEVELOPMENT-#   import qualified Web.Heroku-#   #endif-#-#-#-#   makeFoundation :: AppConfig DefaultEnv Extra -> Logger -> IO App-#   makeFoundation conf setLogger = do-#       manager <- newManager def-#       s <- staticSite-#       hconfig <- loadHerokuConfig-#       dbconf <- withYamlEnvironment "config/postgresql.yml" (appEnv conf)-#                 (Database.Persist.Store.loadConfig . combineMappings hconfig) >>=-#                 Database.Persist.Store.applyEnv-#       p <- Database.Persist.Store.createPoolConfig (dbconf :: Settings.PersistConfig)-#       Database.Persist.Store.runPool dbconf (runMigration migrateAll) p-#       return $ App conf setLogger s p manager dbconf-#-#   #ifndef DEVELOPMENT-#   canonicalizeKey :: (Text, val) -> (Text, val)-#   canonicalizeKey ("dbname", val) = ("database", val)-#   canonicalizeKey pair = pair-#-#   toMapping :: [(Text, Text)] -> AT.Value-#   toMapping xs = AT.Object $ M.fromList $ map (\(key, val) -> (key, AT.String val)) xs-#   #endif-#-#   combineMappings :: AT.Value -> AT.Value -> AT.Value-#   combineMappings (AT.Object m1) (AT.Object m2) = AT.Object $ m1 `M.union` m2-#   combineMappings _ _ = error "Data.Object is not a Mapping."-#-#   loadHerokuConfig :: IO AT.Value-#   loadHerokuConfig = do-#   #ifdef DEVELOPMENT-#       return $ AT.Object M.empty-#   #else-#       Web.Heroku.dbConnParams >>= return . toMapping . map canonicalizeKey-#   #endif--+static-dir:     "_env:STATIC_DIR:static"+host:           "_env:HOST:*4" # any IPv4 host+port:           "_env:PORT:3000"+approot:        "_env:APPROOT:http://localhost:3000"+ip-from-header: "_env:IP_FROM_HEADER:false" -# Heroku setup:-# Find the Heroku guide. Roughly:-#-# * sign up for a heroku account and register your ssh key-# * create a new application on the *cedar* stack-#-# * make your Yesod project the git repository for that application-# * create a deploy branch-#-#     git checkout -b deploy-#-# Repeat these steps to deploy:-# * add your web executable binary (referenced below) to the git repository-#-#     git checkout deploy-#     git add ./dist/build/PROJECTNAME/PROJECTNAME-#     git commit -m deploy-#-# * push to Heroku+# Optional values with the following production defaults.+# In development, they default to the inverse. #-#     git push heroku deploy:master---# Heroku configuration that runs your app-web: ./dist/build/PROJECTNAME/PROJECTNAME production -p $PORT--{-# START_FILE devel.hs #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE PackageImports #-}-import "PROJECTNAME" Application (getApplicationDev)-import Network.Wai.Handler.Warp-    (runSettings, defaultSettings, setPort)-import Control.Concurrent (forkIO)-import System.Directory (doesFileExist, removeFile)-import System.Exit (exitSuccess)-import Control.Concurrent (threadDelay)--#ifndef mingw32_HOST_OS-import System.Posix.Signals (installHandler, sigINT, Handler(Catch))-#endif--main :: IO ()-main = do-#ifndef mingw32_HOST_OS-    _ <- installHandler sigINT (Catch $ return ()) Nothing-#endif--    putStrLn "Starting devel application"-    (port, app) <- getApplicationDev-    forkIO $ runSettings (setPort port defaultSettings) app-    loop--loop :: IO ()-loop = do-  threadDelay 100000-  e <- doesFileExist "yesod-devel/devel-terminate"-  if e then terminateDevel else loop+# development: false+# detailed-logging: false+# should-log-all: false+# reload-templates: false+# mutable-static: false+# skip-combining: false -terminateDevel :: IO ()-terminateDevel = exitSuccess+copyright: Insert copyright statement here+#analytics: UA-YOURCODE -{-# START_FILE messages/en.msg #-}-Hello: Hello+{-# START_FILE config/test-settings.yml #-}+database:+  database: PROJECTNAME_test  {-# START_FILE static/css/bootstrap.css #-} /*!@@ -8835,9 +8762,9 @@             <div id="main" role="main">               ^{pageBody pc}             <footer>-                #{extraCopyright $ appExtra $ settings master}+                #{appCopyright $ appSettings master} -        $maybe analytics <- extraAnalytics $ appExtra $ settings master+        $maybe analytics <- appAnalytics $ appSettings master             <script>               if(!window.location.href.match(/localhost/)){                 window._gaq = [['_setAccount','#{analytics}'],['_trackPageview'],['_trackPageLoadTime']];@@ -8860,7 +8787,7 @@ ^{widget}  {-# START_FILE templates/homepage.hamlet #-}-<h1>_{MsgHello}+<h1>Welcome to Yesod!  <ol>   <li>Now that you have a working project you should use the #@@ -8911,69 +8838,71 @@     color: #990 } -{-# START_FILE test/Handler/HomeSpec.hs #-}-module Handler.HomeSpec-    ( spec-    ) where+{-# START_FILE test/Handler/CommonSpec.hs #-}+module Handler.CommonSpec (spec) where  import TestImport  spec :: Spec-spec =-    ydescribe "These are some example tests" $ do--        yit "loads the index and checks it looks right" $ do-            get HomeR+spec = withApp $ do+    describe "robots.txt" $ do+        it "gives a 200" $ do+            get RobotsR             statusIs 200-            htmlAllContain "h1" "Hello"+        it "has correct User-agent" $ do+            get RobotsR+            bodyContains "User-agent: *"+    describe "favicon.ico" $ do+        it "gives a 200" $ do+            get FaviconR+            statusIs 200 -            request $ do-                setMethod "POST"-                setUrl HomeR-                addNonce-                fileByLabel "Choose a file" "test/Spec.hs" "text/plain" -- talk about self-reference-                byLabel "What's on the file?" "Some Content"+{-# START_FILE test/Handler/HomeSpec.hs #-}+module Handler.HomeSpec (spec) where -            statusIs 200-            -- more debugging printBody-            htmlCount ".message" 1-            htmlAllContain ".message" "Some Content"-            htmlAllContain ".message" "text/plain"+import TestImport -{-# START_FILE test/Spec.hs #-}-module Main where+spec :: Spec+spec = withApp $ do+    it "loads the index and checks it looks right" $ do+        get HomeR+        statusIs 200+        htmlAllContain "h1" "Welcome to Yesod" -import Import-import Yesod.Default.Config-import Yesod.Test-import Test.Hspec (hspec)-import Application (makeFoundation)+        request $ do+            setMethod "POST"+            setUrl HomeR+            addNonce+            fileByLabel "Choose a file" "test/Spec.hs" "text/plain" -- talk about self-reference+            byLabel "What's on the file?" "Some Content" -import qualified Handler.HomeSpec+        statusIs 200+        -- more debugging printBody+        htmlCount ".message" 1+        htmlAllContain ".message" "Some Content"+        htmlAllContain ".message" "text/plain" -main :: IO ()-main = do-    conf <- Yesod.Default.Config.loadConfig $ (configSettings Testing)-                { csParseExtra = parseExtra-                }-    foundation <- makeFoundation conf-    hspec $ do-        yesodSpec foundation $ do-            Handler.HomeSpec.spec+{-# START_FILE test/Spec.hs #-}+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}  {-# START_FILE test/TestImport.hs #-} module TestImport-    ( module Yesod.Test-    , module Foundation-    , module Prelude-    , Spec-    , Example+    ( module TestImport+    , module X     ) where -import Yesod.Test-import Prelude-import Foundation+import Application           (makeFoundation)+import ClassyPrelude         as X+import Foundation            as X+import Test.Hspec            as X+import Yesod.Default.Config2 (ignoreEnv, loadAppSettings)+import Yesod.Test            as X -type Spec = YesodSpec App-type Example = YesodExample App+withApp :: SpecWith App -> Spec+withApp = before $ do+    settings <- loadAppSettings+        ["config/test-settings.yml", "config/settings.yml"]+        []+        ignoreEnv+    makeFoundation settings 
hsfiles/sqlite.hsfiles view
@@ -28,32 +28,31 @@ {-# START_FILE Application.hs #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Application-    ( makeApplication-    , getApplicationDev+    ( getApplicationDev+    , appMain+    , develMain     , makeFoundation     ) where +import Control.Monad.Logger                 (liftLoc, runLoggingT)+import Database.Persist.Sqlite              (createSqlitePool, runSqlPool,+                                             sqlDatabase, sqlPoolSize) import Import-import Yesod.Auth-import Yesod.Default.Config-import Yesod.Default.Main-import Yesod.Default.Handlers-import Network.Wai.Middleware.RequestLogger-    ( mkRequestLogger, outputFormat, OutputFormat (..), IPAddrSource (..), destination-    )-import qualified Network.Wai.Middleware.RequestLogger as RequestLogger-import qualified Database.Persist-import Database.Persist.Sql (runMigration)-import Database.Persist.Sqlite (createSqlitePool, sqlDatabase, sqlPoolSize)-import Network.HTTP.Client.Conduit (newManager)-import Control.Monad.Logger (runLoggingT)-import System.Log.FastLogger (newStdoutLoggerSet, defaultBufSize)-import Network.Wai.Logger (clockDateCacher)-import Data.Default (def)-import Yesod.Core.Types (loggerSet, Logger (Logger))+import Language.Haskell.TH.Syntax           (qLocation)+import Network.Wai.Handler.Warp             (Settings, defaultSettings,+                                             defaultShouldDisplayException,+                                             runSettings, setHost,+                                             setOnException, setPort)+import Network.Wai.Middleware.RequestLogger (Destination (Logger),+                                             IPAddrSource (..),+                                             OutputFormat (..), destination,+                                             mkRequestLogger, outputFormat)+import System.Log.FastLogger                (defaultBufSize, newStdoutLoggerSet,+                                             toLogStr)  -- Import all relevant handler modules here. -- Don't forget to add new modules to your cabal file!+import Handler.Common import Handler.Home  -- This line actually creates our YesodDispatch instance. It is the second half@@ -61,112 +60,136 @@ -- 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+-- | This function allocates resources (such as a database connection pool),+-- performs initialization and return a foundation datatype value. This is also+-- the place to put your migrate statements to have automatic database -- migrations handled by Yesod.-makeApplication :: AppConfig DefaultEnv Extra -> IO (Application, LogFunc)-makeApplication conf = do-    foundation <- makeFoundation conf+makeFoundation :: AppSettings -> IO App+makeFoundation appSettings = do+    -- Some basic initializations: HTTP connection manager, logger, and static+    -- subsite.+    appHttpManager <- newManager+    appLogger <- newStdoutLoggerSet defaultBufSize >>= makeYesodLogger+    appStatic <-+        (if appMutableStatic appSettings then staticDevel else static)+        (appStaticDir appSettings) -    -- Initialize the logging middleware+    -- We need a log function to create a connection pool. We need a connection+    -- pool to create our foundation. And we need our foundation to get a+    -- logging function. To get out of this loop, we initially create a+    -- temporary foundation without a real connection pool, get a log function+    -- from there, and then create the real foundation.+    let mkFoundation appConnPool = App {..}+        tempFoundation = mkFoundation $ error "connPool forced in tempFoundation"+        logFunc = messageLoggerSource tempFoundation appLogger++    -- Create the database connection pool+    pool <- flip runLoggingT logFunc $ createSqlitePool+        (sqlDatabase $ appDatabaseConf appSettings)+        (sqlPoolSize $ appDatabaseConf appSettings)++    -- Perform database migration using our application's logging settings.+    runLoggingT (runSqlPool (runMigration migrateAll) pool) logFunc++    -- Return the foundation+    return $ mkFoundation pool++-- | Convert our foundation to a WAI Application by calling @toWaiAppPlain@ and+-- applyng some additional middlewares.+makeApplication :: App -> IO Application+makeApplication foundation = do     logWare <- mkRequestLogger def         { outputFormat =-            if development+            if appDetailedRequestLogging $ appSettings foundation                 then Detailed True-                else Apache FromSocket-        , destination = RequestLogger.Logger $ loggerSet $ appLogger foundation+                else Apache+                        (if appIpFromHeader $ appSettings foundation+                            then FromFallback+                            else FromSocket)+        , destination = Logger $ loggerSet $ appLogger foundation         }      -- Create the WAI application and apply middlewares-    app <- toWaiAppPlain foundation-    let logFunc = messageLoggerSource foundation (appLogger foundation)-    return (logWare $ defaultMiddlewaresNoLogging app, logFunc)+    appPlain <- toWaiAppPlain foundation+    return $ logWare $ defaultMiddlewaresNoLogging appPlain --- | Loads up any necessary settings, creates your foundation datatype, and--- performs some initialization.-makeFoundation :: AppConfig DefaultEnv Extra -> IO App-makeFoundation conf = do-    manager <- newManager-    s <- staticSite-    dbconf <- withYamlEnvironment "config/sqlite.yml" (appEnv conf)-              Database.Persist.loadConfig >>=-              Database.Persist.applyEnv+-- | Warp settings for the given foundation value.+warpSettings :: App -> Settings+warpSettings foundation =+      setPort (appPort $ appSettings foundation)+    $ setHost (appHost $ appSettings foundation)+    $ setOnException (\_req e ->+        when (defaultShouldDisplayException e) $ messageLoggerSource+            foundation+            (appLogger foundation)+            $(qLocation >>= liftLoc)+            "yesod"+            LevelError+            (toLogStr $ "Exception from Warp: " ++ show e))+      defaultSettings -    loggerSet' <- newStdoutLoggerSet defaultBufSize-    (getter, _) <- clockDateCacher+-- | For yesod devel, return the Warp settings and WAI Application.+getApplicationDev :: IO (Settings, Application)+getApplicationDev = do+    settings <- loadAppSettings [configSettingsYml] [] useEnv+    foundation <- makeFoundation settings+    app <- makeApplication foundation+    wsettings <- getDevSettings $ warpSettings foundation+    return (wsettings, app) -    let logger = Yesod.Core.Types.Logger loggerSet' getter-        mkFoundation p = App-            { settings = conf-            , getStatic = s-            , connPool = p-            , httpManager = manager-            , persistConfig = dbconf-            , appLogger = logger-            }-        tempFoundation = mkFoundation $ error "connPool forced in tempFoundation"-        logFunc = messageLoggerSource tempFoundation logger+-- | main function for use by yesod devel+develMain :: IO ()+develMain = develMainHelper getApplicationDev -    p <- flip runLoggingT logFunc-       $ createSqlitePool (sqlDatabase dbconf) (sqlPoolSize dbconf)-    let foundation = mkFoundation p+-- | The @main@ function for an executable running this site.+appMain :: IO ()+appMain = do+    -- Get the settings from all relevant sources+    settings <- loadAppSettingsArgs+        -- fall back to compile-time values, set to [] to require values at runtime+        [configSettingsYmlValue] -    -- Perform database migration using our application's logging settings.-    flip runLoggingT logFunc-        (Database.Persist.runPool dbconf (runMigration migrateAll) p)+        -- allow environment variables to override+        useEnv -    return foundation+    -- Generate the foundation from the settings+    foundation <- makeFoundation settings --- for yesod devel-getApplicationDev :: IO (Int, Application)-getApplicationDev =-    defaultDevelApp loader (fmap fst . makeApplication)-  where-    loader = Yesod.Default.Config.loadConfig (configSettings Development)-        { csParseExtra = parseExtra-        }+    -- Generate a WAI Application from the foundation+    app <- makeApplication foundation +    -- Run the application with Warp+    runSettings (warpSettings foundation) app+ {-# START_FILE Foundation.hs #-} module Foundation where -import Prelude-import Yesod-import Yesod.Static-import Yesod.Auth-import Yesod.Auth.BrowserId-import Yesod.Default.Config-import Yesod.Default.Util (addStaticContentExternal)-import Network.HTTP.Client.Conduit (Manager, HasHttpManager (getHttpManager))-import qualified Settings-import Settings.Development (development)-import qualified Database.Persist-import Database.Persist.Sql (SqlBackend)-import Settings.StaticFiles-import Settings (widgetFile, Extra (..))+import ClassyPrelude.Yesod+import Database.Persist.Sql (ConnectionPool, runSqlPool) import Model-import Text.Jasmine (minifym)-import Text.Hamlet (hamletFile)-import Yesod.Core.Types (Logger)+import Settings+import Settings.StaticFiles+import Text.Hamlet          (hamletFile)+import Text.Jasmine         (minifym)+import Yesod.Auth+import Yesod.Auth.BrowserId (authBrowserId)+import Yesod.Core.Types     (Logger)+import Yesod.Default.Util   (addStaticContentExternal) --- | The site argument for your application. This can be a good place to+-- | The foundation datatype 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.-    , connPool :: Database.Persist.PersistConfigPool Settings.PersistConf -- ^ Database connection pool.-    , httpManager :: Manager-    , persistConfig :: Settings.PersistConf-    , appLogger :: Logger+    { appSettings    :: AppSettings+    , appStatic      :: Static -- ^ Settings for static file serving.+    , appConnPool    :: ConnectionPool -- ^ Database connection pool.+    , appHttpManager :: Manager+    , appLogger      :: Logger     }  instance HasHttpManager App where-    getHttpManager = httpManager---- Set up i18n messages. See the message folder.-mkMessage "App" "messages" "en"+    getHttpManager = appHttpManager  -- This is where we define all of the routes in our application. For a full -- explanation of the syntax, please see:@@ -177,12 +200,15 @@ -- explanation for this split. mkYesodData "App" $(parseRoutesFile "config/routes") +-- | A convenient synonym for creating forms. type Form x = Html -> MForm (HandlerT App IO) (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+    -- Controls the base of generated URLs. For more information on modifying,+    -- see: https://github.com/yesodweb/yesod/wiki/Overriding-approot+    approot = ApprootMaster $ appRoot . appSettings      -- Store session data on the client in encrypted cookies,     -- default session idle timeout is 120 minutes@@ -205,12 +231,6 @@             $(widgetFile "default-layout")         withUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet") -    -- This is done to provide an optimization for serving static files from-    -- a separate domain. Please see the staticRoot setting in Settings.hs-    urlRenderOverride y (StaticR s) =-        Just $ uncurry (joinPath y (Settings.staticRoot $ settings y)) $ renderRoute s-    urlRenderOverride _ _ = Nothing-     -- The page to be redirected to when authentication is required.     authRoute _ = Just $ AuthR LoginR @@ -225,30 +245,38 @@     -- and names them based on a hash of their content. This allows     -- expiration dates to be set far in the future without worry of     -- users receiving stale content.-    addStaticContent =-        addStaticContentExternal minifym genFileName Settings.staticDir (StaticR . flip StaticRoute [])+    addStaticContent ext mime content = do+        master <- getYesod+        let staticDir = appStaticDir $ appSettings master+        addStaticContentExternal+            minifym+            genFileName+            staticDir+            (StaticR . flip StaticRoute [])+            ext+            mime+            content       where         -- Generate a unique filename based on the content itself-        genFileName lbs-            | development = "autogen-" ++ base64md5 lbs-            | otherwise   = base64md5 lbs--    -- Place Javascript at bottom of the body tag so the rest of the page loads first-    jsLoader _ = BottomOfBody+        genFileName lbs = "autogen-" ++ base64md5 lbs      -- What messages should be logged. The following includes all messages when     -- in development, and warnings and errors in production.-    shouldLog _ _source level =-        development || level == LevelWarn || level == LevelError+    shouldLog app _source level =+        appShouldLogAll (appSettings app)+            || level == LevelWarn+            || level == LevelError      makeLogger = return . appLogger  -- How to run database actions. instance YesodPersist App where     type YesodPersistBackend App = SqlBackend-    runDB = defaultRunDB persistConfig connPool+    runDB action = do+        master <- getYesod+        runSqlPool action $ appConnPool master instance YesodPersistRunner App where-    getDBRunner = defaultGetDBRunner connPool+    getDBRunner = defaultGetDBRunner appConnPool  instance YesodAuth App where     type AuthId App = UserId@@ -257,6 +285,8 @@     loginDest _ = HomeR     -- Where to send a user after logout     logoutDest _ = HomeR+    -- Override the above two destinations when a Referer: header is present+    redirectToReferer _ = True      getAuthId creds = runDB $ do         x <- getBy $ UniqueUser $ credsIdent creds@@ -271,7 +301,7 @@     -- You can add other plugins like BrowserID, email or OAuth here     authPlugins _ = [authBrowserId def] -    authHttpManager = httpManager+    authHttpManager = getHttpManager  instance YesodAuthPersist App @@ -280,23 +310,38 @@ instance RenderMessage App FormMessage where     renderMessage _ _ = defaultFormMessage --- | Get the 'Extra' value, used to hold data from the settings.yml file.-getExtra :: Handler Extra-getExtra = fmap (appExtra . settings) getYesod---- Note: previous versions of the scaffolding included a deliver function to--- send emails. Unfortunately, there are too many different options for us to--- give a reasonable default. Instead, the information is available on the--- wiki:+-- Note: Some functionality previously present in the scaffolding has been+-- moved to documentation in the Wiki. Following are some hopefully helpful+-- links: -- -- https://github.com/yesodweb/yesod/wiki/Sending-email+-- https://github.com/yesodweb/yesod/wiki/Serve-static-files-from-a-separate-domain+-- https://github.com/yesodweb/yesod/wiki/i18n-messages-in-the-scaffolding +{-# START_FILE Handler/Common.hs #-}+-- | Common handler functions.+module Handler.Common where++import Data.FileEmbed (embedFile)+import Import++-- These handlers embed files in the executable at compile time to avoid a+-- runtime dependency, and for efficiency.++getFaviconR :: Handler TypedContent+getFaviconR = return $ TypedContent "image/x-icon"+                     $ toContent $(embedFile "config/favicon.ico")++getRobotsR :: Handler TypedContent+getRobotsR = return $ TypedContent typePlain+                    $ toContent $(embedFile "config/robots.txt")+ {-# START_FILE Handler/Home.hs #-} module Handler.Home where  import Import-import Yesod.Form.Bootstrap3-    ( BootstrapFormLayout (..), renderBootstrap3, withSmallInput )+import Yesod.Form.Bootstrap3 (BootstrapFormLayout (..), renderBootstrap3,+                              withSmallInput)  -- This is a handler function for the GET request method on the HomeR -- resource pattern. All of your resource patterns are defined in@@ -338,40 +383,20 @@     ( module Import     ) where -import           Prelude              as Import hiding (head, init, last,-                                                 readFile, tail, writeFile)-import           Yesod                as Import hiding (Route (..))--import           Control.Applicative  as Import (pure, (<$>), (<*>))-import           Data.Text            as Import (Text)--import           Foundation           as Import-import           Model                as Import-import           Settings             as Import-import           Settings.Development as Import-import           Settings.StaticFiles as Import--#if __GLASGOW_HASKELL__ >= 704-import           Data.Monoid          as Import-                                                 (Monoid (mappend, mempty, mconcat),-                                                 (<>))-#else-import           Data.Monoid          as Import-                                                 (Monoid (mappend, mempty, mconcat))--infixr 5 <>-(<>) :: Monoid m => m -> m -> m-(<>) = mappend-#endif+import ClassyPrelude.Yesod   as Import+import Foundation            as Import+import Model                 as Import+import Settings              as Import+import Settings.StaticFiles  as Import+import Yesod.Auth            as Import+import Yesod.Core.Types      as Import (loggerSet)+import Yesod.Default.Config2 as Import  {-# START_FILE Model.hs #-} module Model where -import Yesod-import Data.Text (Text)+import ClassyPrelude.Yesod import Database.Persist.Quasi-import Data.Typeable (Typeable)-import Prelude  -- You can define all of your database entities in the entities file. -- You can find more information on persistent and how to declare entities@@ -401,7 +426,7 @@                      Model                      Settings                      Settings.StaticFiles-                     Settings.Development+                     Handler.Common                      Handler.Home      if flag(dev) || flag(library-only)@@ -425,17 +450,21 @@                 DeriveDataTypeable                 ViewPatterns                 TupleSections+                RecordWildCards      build-depends: base                          >= 4          && < 5-                 , yesod                         >= 1.4.0      && < 1.5+                 , yesod                         >= 1.4.1      && < 1.5                  , yesod-core                    >= 1.4.0      && < 1.5                  , yesod-auth                    >= 1.4.0      && < 1.5-                 , yesod-static                  >= 1.4.0      && < 1.5+                 , yesod-static                  >= 1.4.0.3    && < 1.5                  , yesod-form                    >= 1.4.0      && < 1.5+                 , classy-prelude                >= 0.10.2+                 , classy-prelude-conduit        >= 0.10.2+                 , classy-prelude-yesod          >= 0.10.2                  , bytestring                    >= 0.9        && < 0.11                  , text                          >= 0.11       && < 2.0                  , persistent                    >= 2.0        && < 2.2-                 , persistent-sqlite             >= 2.0        && < 2.2+                 , persistent-sqlite             >= 2.1.1      && < 2.2                  , persistent-template           >= 2.0        && < 2.2                  , template-haskell                  , shakespeare                   >= 2.0        && < 2.1@@ -452,10 +481,12 @@                  , monad-logger                  >= 0.3        && < 0.4                  , fast-logger                   >= 2.2        && < 2.3                  , wai-logger                    >= 2.2        && < 2.3--    -- see https://github.com/yesodweb/yesod/issues/814-    if !os(windows)-        build-depends: unix+                 , file-embed+                 , safe+                 , unordered-containers+                 , containers+                 , vector+                 , time  executable         PROJECTNAME     if flag(library-only)@@ -463,9 +494,7 @@      main-is:           main.hs     hs-source-dirs:    app-    build-depends:     base-                     , PROJECTNAME-                     , yesod+    build-depends:     base, PROJECTNAME      ghc-options:       -threaded -O2 -rtsopts -with-rtsopts=-N @@ -493,7 +522,7 @@      build-depends: base                  , PROJECTNAME-                 , yesod-test >= 1.4 && < 1.5+                 , yesod-test >= 1.4.2 && < 1.5                  , yesod-core                  , yesod                  , persistent@@ -502,6 +531,8 @@                  , monad-logger                  , transformers                  , hspec+                 , classy-prelude+                 , classy-prelude-yesod  {-# START_FILE Settings.hs #-} -- | Settings are centralized, as much as possible, into this file. This@@ -511,45 +542,81 @@ -- declared in the Foundation.hs file. module Settings where -import Prelude-import Text.Shakespeare.Text (st)-import Language.Haskell.TH.Syntax-import Database.Persist.Sqlite (SqliteConf)-import Yesod.Default.Config-import Yesod.Default.Util-import Data.Text (Text)-import Data.Yaml-import Control.Applicative-import Settings.Development-import Data.Default (def)-import Text.Hamlet+import ClassyPrelude.Yesod+import Control.Exception           (throw)+import Data.Aeson                  (Result (..), fromJSON, withObject, (.!=),+                                    (.:?))+import Data.FileEmbed              (embedFile)+import Data.Yaml                   (decodeEither')+import Database.Persist.Sqlite     (SqliteConf)+import Language.Haskell.TH.Syntax  (Exp, Name, Q)+import Network.Wai.Handler.Warp    (HostPreference)+import Yesod.Default.Config2       (applyEnvValue, configSettingsYml)+import Yesod.Default.Util          (WidgetFileSettings, widgetFileNoReload,+                                    widgetFileReload) --- | Which Persistent backend this site is using.-type PersistConf = SqliteConf+-- | Runtime settings to configure this application. These settings can be+-- loaded from various sources: defaults, environment variables, config files,+-- theoretically even a database.+data AppSettings = AppSettings+    { appStaticDir              :: String+    -- ^ Directory from which to serve static files.+    , appDatabaseConf           :: SqliteConf+    -- ^ Configuration settings for accessing the database.+    , appRoot                   :: Text+    -- ^ Base for all generated URLs.+    , appHost                   :: HostPreference+    -- ^ Host/interface the server should bind to.+    , appPort                   :: Int+    -- ^ Port to listen on+    , appIpFromHeader           :: Bool+    -- ^ Get the IP address from the header when logging. Useful when sitting+    -- behind a reverse proxy. --- Static setting below. Changing these requires a recompile+    , appDetailedRequestLogging :: Bool+    -- ^ Use detailed request logging system+    , appShouldLogAll           :: Bool+    -- ^ Should all log messages be displayed?+    , appReloadTemplates        :: Bool+    -- ^ Use the reload version of templates+    , appMutableStatic          :: Bool+    -- ^ Assume that files in the static dir may change after compilation+    , appSkipCombining          :: Bool+    -- ^ Perform no stylesheet/script combining --- | The location of static files on your system. This is a file system--- path. The default value works properly with your scaffolded site.-staticDir :: FilePath-staticDir = "static"+    -- Example app-specific configuration values.+    , appCopyright              :: Text+    -- ^ Copyright text to appear in the footer of the page+    , appAnalytics              :: Maybe Text+    -- ^ Google Analytics code+    } --- | The base URL for your static files. As you can see by the default--- value, this can simply be "static" appended to your application root.--- A powerful optimization can be serving static files from a separate--- domain name. This allows you to use a web server optimized for static--- files, more easily set expires and cache values, and avoid possibly--- costly transference of cookies on static files. For more information,--- please see:---   http://code.google.com/speed/page-speed/docs/request.html#ServeFromCookielessDomain------ If you change the resource pattern for StaticR in Foundation.hs, you will--- have to make a corresponding change here.------ To see how this value is used, see urlRenderOverride in Foundation.hs-staticRoot :: AppConfig DefaultEnv x -> Text-staticRoot conf = [st|#{appRoot conf}/static|]+instance FromJSON AppSettings where+    parseJSON = withObject "AppSettings" $ \o -> do+        let defaultDev =+#if DEVELOPMENT+                True+#else+                False+#endif+        appStaticDir              <- o .: "static-dir"+        appDatabaseConf           <- o .: "database"+        appRoot                   <- o .: "approot"+        appHost                   <- fromString <$> o .: "host"+        appPort                   <- o .: "port"+        appIpFromHeader           <- o .: "ip-from-header" +        appDetailedRequestLogging <- o .:? "detailed-logging" .!= defaultDev+        appShouldLogAll           <- o .:? "should-log-all"   .!= defaultDev+        appReloadTemplates        <- o .:? "reload-templates" .!= defaultDev+        appMutableStatic          <- o .:? "mutable-static"   .!= defaultDev+        appSkipCombining          <- o .:? "skip-combining"   .!= defaultDev++        appCopyright              <- o .: "copyright"+        appAnalytics              <- o .:? "analytics"++        return AppSettings {..}+ -- | Settings for 'widgetFile', such as which template languages to support and -- default Hamlet settings. --@@ -558,81 +625,62 @@ -- https://github.com/yesodweb/yesod/wiki/Overriding-widgetFile widgetFileSettings :: WidgetFileSettings widgetFileSettings = def-    { wfsHamletSettings = defaultHamletSettings-        { hamletNewlines = AlwaysNewlines-        }-    } +-- | How static files should be combined.+combineSettings :: CombineSettings+combineSettings = def+ -- The rest of this file contains settings which rarely need changing by a -- user.  widgetFile :: String -> Q Exp-widgetFile = (if development then widgetFileReload-                             else widgetFileNoReload)+widgetFile = (if appReloadTemplates compileTimeAppSettings+                then widgetFileReload+                else widgetFileNoReload)               widgetFileSettings -data Extra = Extra-    { extraCopyright :: Text-    , extraAnalytics :: Maybe Text -- ^ Google Analytics-    } deriving Show+-- | Raw bytes at compile time of @config/settings.yml@+configSettingsYmlBS :: ByteString+configSettingsYmlBS = $(embedFile configSettingsYml) -parseExtra :: DefaultEnv -> Object -> Parser Extra-parseExtra _ o = Extra-    <$> o .:  "copyright"-    <*> o .:? "analytics"+-- | @config/settings.yml@, parsed to a @Value@.+configSettingsYmlValue :: Value+configSettingsYmlValue = either throw id $ decodeEither' configSettingsYmlBS -{-# START_FILE Settings/Development.hs #-}-module Settings.Development where+-- | A version of @AppSettings@ parsed at compile time from @config/settings.yml@.+compileTimeAppSettings :: AppSettings+compileTimeAppSettings =+    case fromJSON $ applyEnvValue False mempty configSettingsYmlValue of+        Error e -> error e+        Success settings -> settings -import Prelude+-- The following two functions can be used to combine multiple CSS or JS files+-- at compile time to decrease the number of http requests.+-- Sample usage (inside a Widget):+--+-- > $(combineStylesheets 'StaticR [style1_css, style2_css]) -development :: Bool-development =-#if DEVELOPMENT-  True-#else-  False-#endif+combineStylesheets :: Name -> [Route Static] -> Q Exp+combineStylesheets = combineStylesheets'+    (appSkipCombining compileTimeAppSettings)+    combineSettings -production :: Bool-production = not development+combineScripts :: Name -> [Route Static] -> Q Exp+combineScripts = combineScripts'+    (appSkipCombining compileTimeAppSettings)+    combineSettings  {-# START_FILE Settings/StaticFiles.hs #-} module Settings.StaticFiles where -import Prelude (IO)-import Yesod.Static-import qualified Yesod.Static as Static-import Settings (staticDir)-import Settings.Development-import Language.Haskell.TH (Q, Exp, Name)-import Data.Default (def)---- | use this to create your static file serving site-staticSite :: IO Static.Static-staticSite = if development then Static.staticDevel staticDir-                            else Static.static      staticDir+import Settings     (appStaticDir, compileTimeAppSettings)+import Yesod.Static (staticFiles)  -- | This generates easy references to files in the static directory at compile time, --   giving you compile-time verification that referenced files exist. --   Warning: any files added to your static directory during run-time can't be --   accessed this way. You'll have to use their FilePath or URL to access them.-$(staticFiles Settings.staticDir)--combineSettings :: CombineSettings-combineSettings = def---- The following two functions can be used to combine multiple CSS or JS files--- at compile time to decrease the number of http requests.--- Sample usage (inside a Widget):------ > $(combineStylesheets 'StaticR [style1_css, style2_css])--combineStylesheets :: Name -> [Route Static] -> Q Exp-combineStylesheets = combineStylesheets' development combineSettings--combineScripts :: Name -> [Route Static] -> Q Exp-combineScripts = combineScripts' development combineSettings+staticFiles (appStaticDir compileTimeAppSettings)  {-# START_FILE app/DevelMain.hs #-} -- | Development version to be run inside GHCi.@@ -699,19 +747,24 @@ start :: MVar () -- ^ Written to when the thread is killed.       -> IO ThreadId start done = do-    (port,app) <- getApplicationDev-    forkIO (finally (runSettings (setPort port defaultSettings) app)+    (settings,app) <- getApplicationDev+    forkIO (finally (runSettings settings app)                     (putMVar done ())) +{-# START_FILE app/devel.hs #-}+{-# LANGUAGE PackageImports #-}+import "PROJECTNAME" Application (develMain)+import Prelude (IO)++main :: IO ()+main = develMain+ {-# START_FILE app/main.hs #-}-import Prelude              (IO)-import Yesod.Default.Config (fromArgs)-import Yesod.Default.Main   (defaultMainLog)-import Settings             (parseExtra)-import Application          (makeApplication)+import Prelude     (IO)+import Application (appMain)  main :: IO ()-main = defaultMainLog (fromArgs parseExtra) makeApplication+main = appMain  {-# START_FILE BASE64 config/favicon.ico #-} AAABAAIAEBAAAAEAIABoBAAAJgAAABAQAgABAAEAsAAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAA@@ -820,7 +873,7 @@ User-agent: *  {-# START_FILE config/routes #-}-/static StaticR Static getStatic+/static StaticR Static appStatic /auth   AuthR   Auth   getAuth  /favicon.ico FaviconR GET@@ -829,25 +882,28 @@ / HomeR GET POST  {-# START_FILE config/settings.yml #-}-Default: &defaults-  host: "*4" # any IPv4 host-  port: 3000-  approot: "http://localhost:3000"-  copyright: Insert copyright statement here-  #analytics: UA-YOURCODE--Development:-  <<: *defaults+static-dir:     "_env:STATIC_DIR:static"+host:           "_env:HOST:*4" # any IPv4 host+port:           "_env:PORT:3000"+approot:        "_env:APPROOT:http://localhost:3000"+ip-from-header: "_env:IP_FROM_HEADER:false" -Testing:-  <<: *defaults+# Optional values with the following production defaults.+# In development, they default to the inverse.+#+# development: false+# detailed-logging: false+# should-log-all: false+# reload-templates: false+# mutable-static: false+# skip-combining: false -Staging:-  <<: *defaults+database:+  database: "_env:SQLITE_DATABASE:PROJECTNAME.sqlite3"+  poolsize: "_env:SQLITE_POOLSIZE:10" -Production:-  #approot: "http://www.example.com"-  <<: *defaults+copyright: Insert copyright statement here+#analytics: UA-YOURCODE  {-# START_FILE config/sqlite.yml #-} Default: &defaults@@ -871,135 +927,9 @@   poolsize: 100   <<: *defaults -{-# START_FILE deploy/Procfile #-}-# Free deployment to Heroku.-#-#   !! Warning: You must use a 64 bit machine to compile !!-#-#   This could mean using a virtual machine. Give your VM as much memory as you can to speed up linking.-#-# Basic Yesod setup:-#-# * Move this file out of the deploy directory and into your root directory-#-#     mv deploy/Procfile ./-#-# * Create an empty package.json-#     echo '{ "name": "PROJECTNAME", "version": "0.0.1", "dependencies": {} }' >> package.json-#-# Postgresql Yesod setup:-#-# * add dependencies on the "heroku", "aeson" and "unordered-containers" packages in your cabal file-#-# * add code in Application.hs to use the heroku package and load the connection parameters.-#   The below works for Postgresql.-#-#   import Data.HashMap.Strict as H-#   import Data.Aeson.Types as AT-#   #ifndef DEVELOPMENT-#   import qualified Web.Heroku-#   #endif-#-#-#-#   makeFoundation :: AppConfig DefaultEnv Extra -> Logger -> IO App-#   makeFoundation conf setLogger = do-#       manager <- newManager def-#       s <- staticSite-#       hconfig <- loadHerokuConfig-#       dbconf <- withYamlEnvironment "config/postgresql.yml" (appEnv conf)-#                 (Database.Persist.Store.loadConfig . combineMappings hconfig) >>=-#                 Database.Persist.Store.applyEnv-#       p <- Database.Persist.Store.createPoolConfig (dbconf :: Settings.PersistConfig)-#       Database.Persist.Store.runPool dbconf (runMigration migrateAll) p-#       return $ App conf setLogger s p manager dbconf-#-#   #ifndef DEVELOPMENT-#   canonicalizeKey :: (Text, val) -> (Text, val)-#   canonicalizeKey ("dbname", val) = ("database", val)-#   canonicalizeKey pair = pair-#-#   toMapping :: [(Text, Text)] -> AT.Value-#   toMapping xs = AT.Object $ M.fromList $ map (\(key, val) -> (key, AT.String val)) xs-#   #endif-#-#   combineMappings :: AT.Value -> AT.Value -> AT.Value-#   combineMappings (AT.Object m1) (AT.Object m2) = AT.Object $ m1 `M.union` m2-#   combineMappings _ _ = error "Data.Object is not a Mapping."-#-#   loadHerokuConfig :: IO AT.Value-#   loadHerokuConfig = do-#   #ifdef DEVELOPMENT-#       return $ AT.Object M.empty-#   #else-#       Web.Heroku.dbConnParams >>= return . toMapping . map canonicalizeKey-#   #endif----# Heroku setup:-# Find the Heroku guide. Roughly:-#-# * sign up for a heroku account and register your ssh key-# * create a new application on the *cedar* stack-#-# * make your Yesod project the git repository for that application-# * create a deploy branch-#-#     git checkout -b deploy-#-# Repeat these steps to deploy:-# * add your web executable binary (referenced below) to the git repository-#-#     git checkout deploy-#     git add ./dist/build/PROJECTNAME/PROJECTNAME-#     git commit -m deploy-#-# * push to Heroku-#-#     git push heroku deploy:master---# Heroku configuration that runs your app-web: ./dist/build/PROJECTNAME/PROJECTNAME production -p $PORT--{-# START_FILE devel.hs #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE PackageImports #-}-import "PROJECTNAME" Application (getApplicationDev)-import Network.Wai.Handler.Warp-    (runSettings, defaultSettings, setPort)-import Control.Concurrent (forkIO)-import System.Directory (doesFileExist, removeFile)-import System.Exit (exitSuccess)-import Control.Concurrent (threadDelay)--#ifndef mingw32_HOST_OS-import System.Posix.Signals (installHandler, sigINT, Handler(Catch))-#endif--main :: IO ()-main = do-#ifndef mingw32_HOST_OS-    _ <- installHandler sigINT (Catch $ return ()) Nothing-#endif--    putStrLn "Starting devel application"-    (port, app) <- getApplicationDev-    forkIO $ runSettings (setPort port defaultSettings) app-    loop--loop :: IO ()-loop = do-  threadDelay 100000-  e <- doesFileExist "yesod-devel/devel-terminate"-  if e then terminateDevel else loop--terminateDevel :: IO ()-terminateDevel = exitSuccess--{-# START_FILE messages/en.msg #-}-Hello: Hello+{-# START_FILE config/test-settings.yml #-}+database:+  database: PROJECTNAME_test.sqlite3  {-# START_FILE static/css/bootstrap.css #-} /*!@@ -8965,9 +8895,9 @@             <div id="main" role="main">               ^{pageBody pc}             <footer>-                #{extraCopyright $ appExtra $ settings master}+                #{appCopyright $ appSettings master} -        $maybe analytics <- extraAnalytics $ appExtra $ settings master+        $maybe analytics <- appAnalytics $ appSettings master             <script>               if(!window.location.href.match(/localhost/)){                 window._gaq = [['_setAccount','#{analytics}'],['_trackPageview'],['_trackPageLoadTime']];@@ -8990,7 +8920,7 @@ ^{widget}  {-# START_FILE templates/homepage.hamlet #-}-<h1>_{MsgHello}+<h1>Welcome to Yesod!  <ol>   <li>Now that you have a working project you should use the #@@ -9041,92 +8971,88 @@     color: #990 } -{-# START_FILE test/Handler/HomeSpec.hs #-}-module Handler.HomeSpec-    ( spec-    ) where+{-# START_FILE test/Handler/CommonSpec.hs #-}+module Handler.CommonSpec (spec) where  import TestImport-import qualified Data.List as L  spec :: Spec-spec =-    ydescribe "These are some example tests" $ do--        yit "loads the index and checks it looks right" $ do-            get HomeR+spec = withApp $ do+    describe "robots.txt" $ do+        it "gives a 200" $ do+            get RobotsR             statusIs 200-            htmlAllContain "h1" "Hello"+        it "has correct User-agent" $ do+            get RobotsR+            bodyContains "User-agent: *"+    describe "favicon.ico" $ do+        it "gives a 200" $ do+            get FaviconR+            statusIs 200 -            request $ do-                setMethod "POST"-                setUrl HomeR-                addNonce-                fileByLabel "Choose a file" "test/Spec.hs" "text/plain" -- talk about self-reference-                byLabel "What's on the file?" "Some Content"+{-# START_FILE test/Handler/HomeSpec.hs #-}+module Handler.HomeSpec (spec) where -            statusIs 200-            -- more debugging printBody-            htmlCount ".message" 1-            htmlAllContain ".message" "Some Content"-            htmlAllContain ".message" "text/plain"+import TestImport -        -- This is a simple example of using a database access in a test.  The-        -- test will succeed for a fresh scaffolded site with an empty database,-        -- but will fail on an existing database with a non-empty user table.-        yit "leaves the user table empty" $ do-            get HomeR-            statusIs 200-            users <- runDB $ selectList ([] :: [Filter User]) []-            assertEqual "user table empty" 0 $ L.length users+spec :: Spec+spec = withApp $ do+    it "loads the index and checks it looks right" $ do+        get HomeR+        statusIs 200+        htmlAllContain "h1" "Welcome to Yesod" -{-# START_FILE test/Spec.hs #-}-module Main where+        request $ do+            setMethod "POST"+            setUrl HomeR+            addNonce+            fileByLabel "Choose a file" "test/Spec.hs" "text/plain" -- talk about self-reference+            byLabel "What's on the file?" "Some Content" -import Import-import Yesod.Default.Config-import Yesod.Test-import Test.Hspec (hspec)-import Application (makeFoundation)+        statusIs 200+        -- more debugging printBody+        htmlCount ".message" 1+        htmlAllContain ".message" "Some Content"+        htmlAllContain ".message" "text/plain" -import qualified Handler.HomeSpec+    -- This is a simple example of using a database access in a test.  The+    -- test will succeed for a fresh scaffolded site with an empty database,+    -- but will fail on an existing database with a non-empty user table.+    it "leaves the user table empty" $ do+        get HomeR+        statusIs 200+        users <- runDB $ selectList ([] :: [Filter User]) []+        assertEqual "user table empty" 0 $ length users -main :: IO ()-main = do-    conf <- Yesod.Default.Config.loadConfig $ (configSettings Testing)-                { csParseExtra = parseExtra-                }-    foundation <- makeFoundation conf-    hspec $ do-        yesodSpec foundation $ do-            Handler.HomeSpec.spec+{-# START_FILE test/Spec.hs #-}+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}  {-# START_FILE test/TestImport.hs #-} module TestImport-    ( module Yesod.Test-    , module Model-    , module Foundation-    , module Database.Persist-    , module Prelude-    , runDB-    , Spec-    , Example+    ( module TestImport+    , module X     ) where -import Yesod.Test-import Database.Persist hiding (get)-import Database.Persist.Sql (SqlPersistM, runSqlPersistMPool)-import Control.Monad.IO.Class (liftIO)-import Prelude--import Foundation-import Model--type Spec = YesodSpec App-type Example = YesodExample App+import Application           (makeFoundation)+import ClassyPrelude         as X+import Database.Persist      as X hiding (get)+import Database.Persist.Sql  (SqlPersistM, runSqlPersistMPool)+import Foundation            as X+import Model                 as X+import Test.Hspec            as X+import Yesod.Default.Config2 (ignoreEnv, loadAppSettings)+import Yesod.Test            as X -runDB :: SqlPersistM a -> Example a+runDB :: SqlPersistM a -> YesodExample App a runDB query = do-    pool <- fmap connPool getTestYesod+    pool <- fmap appConnPool getTestYesod     liftIO $ runSqlPersistMPool query pool++withApp :: SpecWith App -> Spec+withApp = before $ do+    settings <- loadAppSettings+        ["config/test-settings.yml", "config/settings.yml"]+        []+        ignoreEnv+    makeFoundation settings 
yesod-bin.cabal view
@@ -1,5 +1,5 @@ name:            yesod-bin-version:         1.4.0.9+version:         1.4.1 license:         MIT license-file:    LICENSE author:          Michael Snoyman <michael@snoyman.com>