Is there a way to get the "current route" in Happstack?

213 views Asked by At

Whenever I use a form in my website, I need to pass an "action" attribute to it (I don't want to leave it empty because I prefer to have validating markup). Right now it looks like this:

registerPage = dir "test" $ do
    nullDir
    let action = "/test" :: String
    let mkForm = form action
    let prefix = "register"
    eForm <- happstackEitherForm mkForm prefix registerForm

For forms where the action is the same page they are in, I don't like needing to write the URL twice as I am currently doing. Is there a way to get the "current url" instead?

registerPage = dir "test" $ do
    nullDir
    action <- {- ... -}

The best alternative I have so far is turning the action into an explicit parameter / variable

registerUrl :: String
registerUrl = "register"

registerPage = dir registerUrl $ do
    nullDir
    let action = "/" ++ registerUrl

but if I do that then I'll have one extra parameter that I will need to name and pass around to my functions. I also think that needing to do that "/" ++ is a bit ugly.

2

There are 2 answers

3
hugomg On BEST ANSWER

Now that I think of it, I think what I actually needed was the current URL, as sent by the user and irrespective of what routing filters I used. This will preserve variable path segments and query string parameters.

To do that, I can get the current Request via askRq and get the URL from it via rqUri and rqQuery

rq <- askRq
let action = (rqUri rq) ++ (rqQuery rq)
3
Tom Ellis On

Do you want this:

import Control.Monad (MonadPlus)
import Happstack.Server.SimpleHTTP (dir, ServerMonad)

dir' :: (MonadPlus m, ServerMonad m) => String -> (String -> m a) -> m a
dir' path handler = dir path (handler ("/" ++ path))

registerPage = dir' "test" $ \action -> do
    nullDir
    ... use action ...

I don't know if dir' already exists in Happstack.