happs-tutorial 0.9.3 → 0.9.4
raw patch · 5 files changed
+50/−61 lines, 5 filesdep ~HStringTemplatedep ~HTTPdep ~bytestring
Dependency ranges changed: HStringTemplate, HTTP, bytestring, happstack, happstack-data, happstack-helpers, happstack-ixset, happstack-server, happstack-state
Files
- happs-tutorial.cabal +11/−10
- src/ControllerPostActions.hs +21/−24
- src/Main.hs +3/−2
- templates/footer.st +1/−1
- templates/runtutoriallocally.st +14/−24
happs-tutorial.cabal view
@@ -1,5 +1,5 @@ Name: happs-tutorial-Version: 0.9.3+Version: 0.9.4 Synopsis: A Happstack Tutorial that is its own web 2.0-type demo. Description: A nice way to learn how to build web sites with Happstack @@ -48,26 +48,27 @@ View ghc-options: -Wall Build-Depends: base- , HStringTemplate >= 0.4.0 && < 0.5.0+ -- , HStringTemplate >= 0.4.0 && < 0.5.0 + , HStringTemplate >= 0.6 , HStringTemplateHelpers >= 0.0.14 && < 1.0.0 , mtl >= 1.1.0.0 && < 2.0.0.0 - , bytestring >= 0.9.0.0 && < 0.10.0.0- , happstack >= 0.3 && < 0.5+ , bytestring + , happstack >= 0.5 , containers >= 0.2.0.0 && < 0.3.0.0 , pretty >= 1.0.1.0 && < 2 , pureMD5 >= 1.0.0.0 && < 1.1.0.0 , directory >= 1.0.0.0 && < 1.1.0.0 , filepath >= 1.1.0.0 && < 1.2.0.0 , hscolour == 1.13- , HTTP >= 4000.0.7 && < 4000.0.8+ , HTTP >= 4000 , safe >= 0.2 && < 0.3 , old-time >= 1.0.0.0 && < 1.1.0.0 , parsec >= 2.1.0.0 && < 2.2.0.0- , happstack-helpers >= 0.43 && < 0.50+ , happstack-helpers >= 0.50 , DebugTraceHelpers >= 0.12 && < 0.20- , happstack-server >= 0.3 && < 0.5- , happstack-data >= 0.3 && < 0.5- , happstack-ixset >= 0.3 && < 0.5- , happstack-state >= 0.3 && < 0.5+ , happstack-server >= 0.5+ , happstack-data >= 0.5+ , happstack-ixset >= 0.5+ , happstack-state >= 0.5 if flag(base4) Build-Depends: base >=4 && <5, syb
src/ControllerPostActions.hs view
@@ -19,31 +19,32 @@ loginPage :: RenderGlobals -> ServerPartT IO Response-loginPage rglobs@(RenderGlobals rq _ _) = - -- unfortunately can't just use rqUrl rq here, because sometimes has port numbers and... it gets complicated- case tutAppReferrer rq of- Left e -> return $ errW rglobs e- Right landingpage -> loginPage' authUser (const startsess') rglobs landingpage +loginPage rglobs = do+ ref <- runErrorT tutAppReferrer + let landingpage = fromEither "/" $ ref -- tutAppReferrer rq+ loginPage' authUser (const startsess') rglobs landingpage where authUser = authUser' getUserPassword getUserPassword name = return . maybe Nothing (Just . B.unpack . password) =<< query (GetUserInfos name) +-- move to common code/helpers+fromEither :: a -> Either e a -> a+fromEither def (Left _) = def+fromEither _ (Right x) = x+ -- move this to HAppSHelpers-tutAppReferrer :: Request -> Either String String-tutAppReferrer rq = do- let approot :: Either String String- approot = modRewriteAppUrl "" rq - case approot of - Left _ -> Left $ "tutAppReferrer, could not determine approot, rq: " ++ (show rq)- Right ar ->- case getHeaderVal "referer" rq of - Left e -> Left $ "smartAppReferrer error, rq: " ++ e- -- check against logout, otherwise if you have just logged out then - -- try immediately to log in again it won't let you.- Right rf -> if isInfixOf "logout" rf || isInfixOf "login" rf || isInfixOf "newuser" rf- then Right ar- else Right rf+--tutAppReferrer :: Request -> Either String String+tutAppReferrer :: ServerMonad m => ErrorT String m String+tutAppReferrer = do+ -- check against logout, otherwise if you have just logged out then + -- try immediately to log in again it won't let you. (???)+ rf <- ErrorT $ getHeaderVal "referer" `liftM` askRq+ return $ if or $ map (flip isInfixOf rf) ["logout", "login", "newuser"]+ then "/"+ else rf +-- getReferrer = getHeaderVal "referer" =<< askRq+ -- Use a helper function because the plan is to eventually have a similar function -- that works for admin logins loginPage' :: (Monad m) =>@@ -127,14 +128,10 @@ newUserPage :: RenderGlobals -> ServerPartT IO Response newUserPage rglobs = do NewUserInfo user pass1 pass2 <- getData'- rq <- askRq etRes <- runErrorT $ setupNewUser (NewUserInfo user (pass1 :: B.ByteString) pass2) case etRes of Left err -> return $ errW rglobs err - Right () -> case modRewriteAppUrl "tutorial/registered" rq of- Left e -> return $ errW rglobs e- Right p -> startsess' user p- + Right () -> startsess' user "/tutorial/registered" where setupNewUser :: NewUserInfo -> ErrorT String (ServerPartT IO) () setupNewUser (NewUserInfo user pass1 pass2) = do
src/Main.hs view
@@ -17,6 +17,7 @@ let p = read port allowStressTests = read allowStressTests' dynamicTemplateReload = read dynamicTemplateReload'+ --cleanUpLockFile "happs-tutorial" "tutorial.happstack.com" "happstack" 5 tDirGroups <- getTemplateGroups -- defined in Controller.hs {- smartserver and its cousin smartserver' are from the happstack-helpers package. They are essentially a combination startSystemState and simpleHTTP('), with a@@ -25,7 +26,7 @@ Just like with simpleHTTP we pass in the ServerPartT, given by controller from Controller.hs, and just like startSystemState we pass in a Proxy in order to initialize the system state. -}- smartserver (Conf p Nothing) "happs-tutorial"+ smartserver (Conf p Nothing) (controller tDirGroups dynamicTemplateReload allowStressTests) stateProxy _ -> putStrLn "usage example: happs-tutorial 5001 True True (starts the app on port 5001, \@@ -36,7 +37,7 @@ putStrLn $ "happs tutorial running in ghci. \n" ++ "exit :q ghci completely and reenter ghci, before restarting." tDirGroups <- getTemplateGroups- smartserver (Conf 5001 Nothing) "happs-tutorial" (controller tDirGroups True True) stateProxy+ smartserver (Conf 5001 Nothing) (controller tDirGroups True True) stateProxy stateProxy :: Proxy AppState stateProxy = Proxy
@@ -1,7 +1,7 @@ <div id="footer"> happstack tutorial v 0.8.1 <br>- copyright thomashartman1 at gmail, wchogg at gmail + copyright thomashartman1 at gmail, wchogg at gmail (current maintainer is thomas) <br><a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/happs-tutorial">use the source</a> | <a href="/projectroot/templates">browse templates</a> | <a href="/projectroot/src">browse haskell files</a>
templates/runtutoriallocally.st view
@@ -2,34 +2,20 @@ <p> Before going further, you may want to inform yourself about the <a href=/tutorial/prerequisites>basic prerequisites</a>, both knowledge and equipment, you need to make the best use of this tutorial. </p> -<p>This tutorial is cabalized. You can install it, and chase down all the Happstack dependencies it needs, simply by doing -<p>cabal install happs-tutorial</p>--<p>If you've never used cabal install or need more detailed info see the <a href="http://hackage.haskell.org/trac/hackage/wiki/CabalInstall">cabal install</a> homepage.</p>--<p>If you want to use the latest version of this tutorial, install <a href="http://www.darcs.net">Darcs</a> and check out the repo with darcs get http://patch-tag.com/publicrepos/happstack-tutorial.</p>--<p>The reason I cabalized happs-tutorial was for the dependency chasing you get with cabal install,-not for actually running it.</p>-+<p>To fetch the latest version of this tutorial, install <a href="http://www.darcs.net/">darcs</a>, fetch the repo, and run happs-tutorial from within the repo: -<p>Cabal installs an executable somewhere that you can run, but the tutorial pages won't display because-the executable needs template files to display pages correctly. To actually run the tutorial locally, copy the -happs-tutorial.tar.gz distribution file that cabal downloaded -- probably somewhere under ~/.cabal if you're on linux.- The following command </p>+<pre style="margin-left: 1em;">+darcs get http://patch-tag.com/r/wchogg/happstack-tutorial/pullrepo happstack-tutorial+cd happstack-tutorial+cabal install+happs-tutorial 5001 True True+</pre> -<p><i>find ~/.cabal | grep -i happs-tutorial</i> </p>+<p>You should now be able to browse this tutorial offline by running the executable, and opening http://localhost:5001 in your browser.</p> -<p>should show you a tar file. Otherwise, you can just download the tar file from-<a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/happs-tutorial">hackage</a>.-Once you have the tar file, untar this somewhere, cd into that, build and run here as described below. Finally, you could darcs get happs-tutorial and run there.</p>+<p>If you've never used cabal install or need more detailed info see the <a href="http://hackage.haskell.org/trac/hackage/wiki/CabalInstall">cabal install</a> homepage.</p> -<p>To run the app, either do ./hackInGhci.sh and then execute runInGhci inside Main.hs or run the happs-tutorial executable created by cabal install, with the caveat that you do need to be in the base directory of happs-tutorial.- You shouldn't need to run inside of ghci, but the option is available.-<p>Suggested runtime options: <i>happs-tutorial 5001 True True</i></p>-<p>Shutdown with ctrl-c.</p>-<p>-You should now be able to browse this tutorial offline by running the executable, and opening http://localhost:5001 in your browser.</p>+<p>If you prefer to run the app in ghci, do ./hackInGhci.sh and then execute runInGhci inside Main.hs. <p>Every so often, when starting via runInGhci, you may get an error message like:</p> @@ -42,6 +28,10 @@ <p>Don't worry about it. Every time I get this error I simply run runInGhci again, and the second time it always works.</p> <p>This issue does not occur when you run the tutorial from a compiled executable, which is of course how you should be running for a production application.</p>+++<p>If you get the error "`Control.Monad.Trans' was found in multiple packages: transformers-0.1.4.0 mtl-1.1.0.2", you can use the command "ghc-pkg hide transformers" to prevent ghci from seeing the conflicting package.</p>+ <p>You may also want to <a href="start-happstack-on-boot">start Happstack on boot</a>.</p> <p>Next up is a first example of using <a href="/tutorial/your-first-happstack">Happstack</a>.</p>