Search code examples
haskellihp

Change location of controller pages


I have a simple IHP application which converts farenheit to celsius.

I've stripped out many of the files so that the bulk of the app is in the following file:

https://github.com/dharmatech/ConvertTemperatureIhp/blob/000-minimal/Web/FrontController.hs

The contents of that file are shown here:

module Web.FrontController where

import IHP.RouterPrelude

import Application.Helper.Controller
import IHP.ControllerPrelude

import IHP.ViewPrelude
import Generated.Types
import Application.Helper.View


instance AutoRoute TemperatureController 

data WebApplication = WebApplication deriving (Eq, Show)

data TemperatureController
    = FormAction
    | ResultAction
    deriving (Eq, Show, Data)

instance Controller TemperatureController where
    action FormAction = respondHtml

            [hsx|
        
            <form action="/Result" method="post">
                <label>Farenheit</label>
                <input type="text" name="farenheit"/>
            </form>            

        |]
    
    action ResultAction = 
        let
            farenheit = IHP.ControllerPrelude.param @Float "farenheit"
            celsius = (farenheit - 32.0) * 5.0 / 9.0
        in
            respondHtml [hsx| 
                <p>Celsius: {celsius}</p>
            |]

instance FrontController WebApplication where
    controllers = 
        [ 
          parseRoute @TemperatureController 
        ]

instance InitControllerContext WebApplication where
    initContext = do
        initAutoRefresh

If I go to /Form I get the following page:

enter image description here

After submitting that form, the following page is shown:

enter image description here

Question

As you can see, the two pages are at /Form and /Result.

What's a good way to have these show up at:

/Temperature/Form
/Temperature/Result

instead?

Update

Here's a new version of the code based on Marc's answer below:

https://github.com/dharmatech/ConvertTemperatureIhp/blob/002-routing/Web/FrontController.hs


Solution

  • Check out the guide on Custom Routing https://ihp.digitallyinduced.com/Guide/routing.html#custom-routing

    Basically you need to remove the instance AutoRoute TemperatureController and replace it with this:

    instance CanRoute TemperatureController where
        parseRoute' = do
            let form = string "/Temperature/Form" <* endOfInput >> pure FormAction
            let result = string "/Temperature/Result" <* endOfInput >> pure ResultAction
            form <|> result
    
    instance HasPath TemperatureController where
        pathTo FormAction = "/Temperature/Form"
        pathTo ResultAction = "/Temperature/Result"