2

我想测试用户是否经过身份验证并根据状态显示“登录”或“注销”链接。

到目前为止我有

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

但我收到一个错误:

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'
4

1 回答 1

6

maybeAuthId是一个执行数据库和会话相关操作的单子操作。在 Hamlet 模板的定义中不能有单子动作。想象一下如果你写了这个(类似的单子动作)会发生什么:

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

该动作应该多久执行一次;每次渲染模板时?什么时候加载?如果它不只是在终端上打印“Hello World”,它可能会变得非常混乱,即使那样它也不是很安全——您是否希望您的模板文件能够打印到终端、启动核武器或窃取您的信用卡信息?

这就是为什么在所有莎士比亚模板中只允许使用纯值。你需要这样做:

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

(foo.hamlet:)

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

可以看到,maybeAuthId函数会在模板外执行,结果在模板内匹配。这样,您可以确保在您可以确定的特定时间点检查您的会话/数据库,并且您的模板不会注入病毒,因为您的设计师没有得到足够的报酬并采取行动报复你。

顺便说一句,您可能希望使用 aBool来指示用户是否已登录并改用$if语句。您可能希望为此使用模块中的isJust功能Data.Maybe

于 2012-07-29T18:23:15.977 回答