Вопрос

I want to test if the user is authenticated and show a "log in" or "log out" link depending on the state.

So far I have

$maybe muid <- maybeAuthId
    <a href=@{AuthR LogoutR} >Logout
$nothing
    <a href=@{AuthR LoginR} >Login

but I get an error:

Couldn't match expected type `Maybe v0'
            with actual type `GHandler s0 m0 (Maybe (AuthId m0))'
In the first argument of `Text.Hamlet.maybeH', namely `maybeAuthId'
Это было полезно?

Решение

maybeAuthId is a monadic action that performs database and session-related operations. You can't have monadic actions in the definition of a Hamlet template. Imagine what would happen if you wrote this (a similar monadic action):

$maybe a <- liftIO (putStrLn "Hello World") >> return (Just "Hi")
    <p>Just #{a}
$nothing
    <p>Nothing

How often should that action be executed; every time the template is rendered? When it's loaded? It might get very messy if it did something other than just printing "Hello World" to the terminal, and even then it's not very safe -- would you expect your template files to be able to print to the terminal, launch nukes or steal your credit card information?

That's why only pure values are allowed in all Shakespearean templates. You need to do this instead:

getMyHandlerR :: Handler RepHtml
getMyHandlerR = do
  muid <- maybeAuthId
  $(widgetFile "foo")

(foo.hamlet:)

$maybe uid <- muid
  <p>Foo
$nothing
  <p>Bar

As you can see, the maybeAuthId function will be executed outside of the template, and the result is matched within the template. That way, you can make sure that your session/database is checked at a specific point in time that you can determine, and that your template doesn't inject a virus because your designer didn't get paid enough and acted out his revenge on you.

By the way, you might want to use a Bool to indicate whether the user is logged in and use an $if statement instead. You might want to use the isJust function from the Data.Maybe module for that.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top