Happstack 0.2 Release Notes ================================================================================ Project / Code generation tool ------------------------------- There is now a code generation tool for Happstack. This is inspired by the 'rails' command. 1. First install happstack (cabal install happstack) 2. Make sure the cabal bin dir is in your path - in linux this is ~/.cabal/bin - in windows this is C:\Documents and Settings\\Application Data\cabal\bin where is your windows username. 3. Run this command: happstack new project where is the folder you want to create the project in. 4. It will create several folders: - bin (scripts for your project go here) - dist (where deployment files will go) - public (static files for the http server) - src (project source code goes here) - templates (HStringTemplate files go here) 5. There are three scripts to get your project kick-started - bin/build (build a static compiled binary at dist/app) - bin/run (run the project dynamically) - bin/run-interactive (run the project interactively in ghci) Each script has a .sh version if you are on *nix and a .bat version if you are on windows. 6. By default, your project will bind to port 8000 on every ip address your machine has. 7. There are five source files in the src folder by default - AppControl.hs (routing and controller code goes here) - AppState.hs (MACID state objects are defined here) - AppView.hs (presentation / view code goes here) - AppLogger.hs (controls logging for the hslogger system) - Main.hs (entry point to your app, is has the routines needed to run your application) 8. Enjoy! The WebT/ServerPartT change ------------------------------- WebT and ServerPartT have been substantially refactored. They are now built from simpler monads. ServerPartT is now the only monad you have to deal with, most of the time. I.e. you almost never have to look at WebT again. You just have do blocks in ServerPartT. Inside ServerPartT you can get your request (askRq), modify your request (localRq), exit immediately (finishWith), exit failure (mzero), and alter your response filters (composeFilter, setFilter, getFilter) It also lifts ErrorT, ReaderT, WriterT and StateT, so you can embed one of those as well. As a bonus, nearly all the functions you expected to take a WebT or to operate only within a WebT can now work inside a ServerPartT directly. The monad stack handles all the data threading. That being said, here are a list of the non-backwards compatible changes. ServerPartT, WebT, unServerPartT and unWebT now have different semantics. To get existing code to compile you can change your methods like so: ServerPartT -> withRequest WebT -> mkWebT unServerPartT -> runServerPartT unWebT -> ununWebT or runWebT depending on what you're going for. By just making the above changes, your existing code should continue to work as before. However, at this point, any old code you have can be greatly simplified. For example, you will never have to use anyRequest or withRequest to change from ServerPartT to WebT. You never have to interact with WebT directly. You can do everything in a ServerPartT do block. The examples provided in the documentation (especially basicAuth') just barely touch on the power of ServerPartT now. Notice that basicAuth' mixes reading requests and altering responses all without exposing WebT, constructing a ServerPartT, or really doing any data threading at all. As a quick example: This: uriRest :: Monad m => (String -> ServerPartT m a) -> ServerPartT m a uriRest handle = withRequest $ \rq -> unServerPartT (handle (rqURL rq)) rq Becomes this: uriRest :: (ServerMonad m, Monad m) => (String -> m a) -> m a uriRest handle = askRq >>= handle . rqURL Every single function that uses withRequest, anyRequest, unServerPartT, unWebT or ununWebT can be rewritten to take advantage of these simple monad behaviors. Additionally, a lot of functions were added to make it easier to work entirely inside a do block. getHeaderM, addHeaderM, getData, getDataFn, escape', finishWith, getFilter, setFilter, composeFilter, applyFilter, setResponseCode, guardRq, methodM, methodOnly, nullDir, requireM The following were deprecated since they duplicate functionality noHandle -> Use mzero multi -> Use msum method -> you should be able to use methodSP though you'll need to fix your typing modifyResponse -> use composeFilter Also, this release sees the return of simpleHTTP', though not as you knew it before. simpleHTTP must take a ServerPartT IO a. simpleHTTP' lets you use Any ServerPartT m a, as long as you provide a function for unwrapping your interior monad into an IO monad. This is particularly important since ServerPartT has lifting instances for WriterT, StateT, ErrorT, and ReaderT, thus embedding your favorite monad transformer into ServerPartT is easier than ever. Documentation ------------------------------- This release also adds substantial documentation for the package Happstack.Server.SimpleHTTP which convers most of the new structures added, as well as many of your old favorites. Be sure to check it out. Removing list types from SimpleHTTP ------------------------------- Having most of the methods in SimpleHTTP take array types was cumbersome, since often you only had one part and had to wrap it up. All methods that used to take a list of ServerPartTs now only take a single ServerPartT. To convert your list of ServerPartT into a single ServerPartT, use msum. For example: simpleHTTP nullConf [spart1, spart2] Becomes: simpleHTTP nullConf $ msum [spart1, spart2] The functions affected by this change are: simpleHTTP, dir, path, anyPath, withData, withDataFn, require, requireM, xslt, debugFilter, applyRequest, basicAuth, and errorHandlerSP Gzip/Deflate encoding ------------------------------ There is now a ServerPartT for gzip/deflate encoding, in Happstack.Server.Parts.compressedResponseFilter Guidlines for porting existing HAppS and Happstack <= 0.1 code to 0.2 ------------------------------- The first change you should do is change the following functions as described above. ServerPartT -> withRequest WebT -> mkWebT unServerPartT -> runServerPartT unWebT -> ununWebT Next, work on prepending $ msum in front of every list of ServerPartTs, or deleting lists that are no longer necessary. After this point, you should be able to get your app compiled and running. To further clean up your code and take advantage of the new functionality in ServerPartT, the general procedure is as follows: - consider studying the revised examples in happstack-server/Examples. They all use the new idioms. - delete your type signatures that reference WebT or ServerPartT, as after the first step they will all have changed dramatically - delete all uses of withRequest and anyRequest (they aren't needed anymore) - change the idiom 'method m $' to 'methodM m >>' - change 'withRequest \rq -> do ...' to 'do { rq <- askRq; ... }' - change withData \myDat $ \dat -> do ... to do dat <- getData >>= maybe mzero return ... - change withDataFn fn \myDat $ \dat -> do ... to do dat <- getDataFn fn >>= maybe mzero return ... - change all references of noHandle to mzero - you can probably benefit from some do blocks at this point - if you're passing around the request explictly, stop. You can just "rq <- askRq" whenever you need it. - consider embedding your favorite monad transformer into your ServerPartTs. To make this work, you'll want to read the documentation for simpleHTTP', mapServerPartT, and WebT - consider reading the newly minted documentation for Happstack.Server.SimpleHTTP. Hopefully you'll learn something. Windows Bin Path Caveats ------------------------------ By default when you install say ghc 6.8.3 or 6.10.1, windows won't setup the paths. You need to perform these steps after running the installer for ghc: 1. Right Click on "My Computer" 2. Left Click on "Properties" 3. Advanced Tab 4. Environmental Variables 5. Add or Edit existing 'PATH' variable If you have ghc 6.8.3 for instance: 1. Prepend "C:\ghc\ghc-6.8.3;C:\ghc\ghc-6.8.3\bin;" to the Variable value 2. Click OK 3. Restart and cmd windows you have open 6. Now all the commands should work i.e. ghci, ghc-pkg, perl etc. 7. You will need happy to compile happstack Follow these steps: 1. Install happy via cabal install or the manual method 2. Prepend "C:\Documents and Settings\user\Application Data\cabal\bin" to your Environment Path variable where user is your username. 3. Now any binaries installed by cabal packages will also be in your command path.