Настраиваемый префикс пути с Yesod

У меня есть следующий веб-сервер:

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes       #-}
{-# LANGUAGE TemplateHaskell   #-}
{-# LANGUAGE TypeFamilies      #-}
import           Data.Text        (Text)
import           Yesod

data App = App

mkYesod "App" [parseRoutes|
/      HomeR  GET
/link1 Link1R GET
/link2 Link2R GET
/link3 Link3R GET
/link4 Link4R GET
|]

instance Yesod App where

getHomeR :: Handler Html
getHomeR = defaultLayout $ do
    setTitle "Redirects"
    [whamlet|
        <p>
            <a href=@{Link1R}>Click to start the redirect chain!
    |]

getLink1R, getLink2R, getLink3R :: Handler ()
getLink1R = redirect Link2R -- /link2
getLink2R = redirect (Link3R, [("foo", "bar")]) -- /link3?foo=bar
getLink3R = redirect $ Link4R :#: ("baz" :: Text) -- /link4#baz

getLink4R :: Handler Html
getLink4R = defaultLayout
    [whamlet|
        <p>You made it!
    |]

main :: IO ()
main = warp 3000 App

Но у меня есть префикс маршрута откуда-то, например, из переменной окружения:

/prefix/      HomeR  GET
/prefix/link1 Link1R GET
/prefix/link2 Link2R GET
/prefix/link3 Link3R GET
/prefix/link4 Link4R GET

Как мне этого добиться?

Я пробовал approot, но это не работает...


person stevemao    schedule 27.01.2020    source источник
comment
Я не совсем уверен, понимаю ли я, в чем проблема. Что не работает?   -  person Willem Van Onsem    schedule 27.01.2020
comment
Префикс URL исходит из параметра или переменной среды. Я не уверен, как лучше всего это сделать.   -  person stevemao    schedule 27.01.2020
comment
Должна ли она быть переменной во время компиляции или во время выполнения? Если последнее, то для него нельзя использовать Template Haskell.   -  person leftaroundabout    schedule 27.01.2020
comment
Оба могут быть вариантом. В учебных целях, какой лучший способ для обоих? Я новичок в функциональном программировании :) Большое спасибо!   -  person stevemao    schedule 27.01.2020
comment
Я думаю, что время компиляции было бы лучше, но я хотел бы изучить оба решения.   -  person stevemao    schedule 27.01.2020
comment
Ну, опять же, для времени выполнения это не может быть вопрос о TH, а скорее о Йесод. Существует очень простое решение для взлома, если вы можете сделать переменную часть постфиксом, а не префиксом. Но я думаю, что было бы целесообразно сфокусировать вопрос на версии времени компиляции, если вы хотите узнать о Haskell, а не о специфике Yesod.   -  person leftaroundabout    schedule 27.01.2020
comment
Решение времени выполнения не обязательно должно быть связано с TH. Насчет Йесод нормально. Решение времени сборки не обязательно должно быть связано с TH и с тем, что является лучшей практикой в ​​Haskell. Я не могу сделать постфикс пути, но мне интересно узнать, что вы подразумеваете под взломом.   -  person stevemao    schedule 27.01.2020


Ответы (1)


Я использую cleanPath для удаления префикса:

    cleanPath app s =
        if corrected == s
            then Right $ dropPrefix $ map dropDash s
            else Left corrected
      where
        corrected = filter (not . T.null) s
        dropDash t
            | T.all (== '-') t = T.drop 1 t
            | otherwise = t
        dropPrefix s' = case routePrefix $ appSettings app of
            Nothing -> s'
            Just prefix -> case headMay s' of
                            Just t -> if t == prefix then drop 1 s' else ["wrong prefix"]
                            Nothing -> ["wrong prefix"]

Если вы знаете лучший способ сделать это, прокомментируйте или добавьте ответ. Спасибо!

person stevemao    schedule 29.01.2020