Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lookup query parameters in Yesod

I just initialized a Yesod project (no database) using yesod init.

My HomeR GET handler looks like this:

getHomeR :: Handler Html
getHomeR = do
    (formWidget, formEnctype) <- generateFormPost sampleForm
    let submission = Nothing :: Maybe (FileInfo, Text)
        handlerName = "getHomeR" :: Text
    defaultLayout $ do
        aDomId <- newIdent
        setTitle "Welcome To Yesod!"
        $(widgetFile "homepage")

When using yesod devel, I can access the default homepage at http://localhost:3000/.

How can I modify the handler listed above to retrieve (and display) a HTTP GET query parameter like id=abc123 when accessing this URL:

http://localhost:3000/?id=abc123

Note: This question was answered Q&A-style and therefore intentionally doesn't show research effort!

like image 871
Uli Köhler Avatar asked Aug 11 '14 21:08

Uli Köhler


1 Answers

I'll show two different methods to achieve this. For both, you'll need to add this code to your template, e.g. in homepage.hamlet:

Note that it is not guaranteed there is any id parameter present when accessing the URL, therefore the type resulting from both methods is Maybe Text. See the Shakespearean template docs for a detailed explanation of the template parameters.

Method 1: lookupGetParam

The easiest way you can do this is using lookupGetParam like this:

idValueMaybe <- lookupGetParam "id"

When using the default setting as generated by yesod init, idValueMaybe needs to be defined in both getHomeR and postHomeR if idValueMaybe is used in the template.

Your HomeR GET handler could look like this:

getHomeR :: Handler Html
getHomeR = do
    idValueMaybe <- lookupGetParam "id"
    (formWidget, formEnctype) <- generateFormPost sampleForm
    let submission = Nothing :: Maybe (FileInfo, Text)
        handlerName = "getHomeR" :: Text
    defaultLayout $ do
        aDomId <- newIdent
        setTitle "Welcome To Yesod!"
        $(widgetFile "homepage")

Method 2: reqGetParams

Instead of looking up the query parameters by name, you can also retrieve a list of query key/value pairs using reqGetParams. This can be advantageous in certain situations, e.g. if you don't know all possible keys in advance. Using the standard lookup function you can easily lookup a certain key in that list.

The relevant part of your code could look like this:

getParameters <- reqGetParams <$> getRequest
let idValueMaybe = lookup "id" getParameters :: Maybe Text

Your getHomeR could look like this:

getHomeR :: Handler Html
getHomeR = do
    getParameters <- reqGetParams <$> getRequest
    let idValueMaybe = lookup "id" getParameters :: Maybe Text
    (formWidget, formEnctype) <- generateFormPost sampleForm
    let submission = Nothing :: Maybe (FileInfo, Text)
        handlerName = "getHomeR" :: Text
    defaultLayout $ do
        aDomId <- newIdent
        setTitle "Welcome To Yesod!"
        $(widgetFile "homepage")
like image 87
Uli Köhler Avatar answered Nov 09 '22 02:11

Uli Köhler