测试用户是否登录在哈姆雷特模板中

oh_*_*pes 2 haskell yesod hamlet

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

到目前为止我有

$maybe muid <- maybeAuthId
    <a href=@{AuthR LogoutR} >Logout
$nothing
    <a href=@{AuthR LoginR} >Login
Run Code Online (Sandbox Code Playgroud)

但是我收到一个错误:

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'
Run Code Online (Sandbox Code Playgroud)

dfl*_*str 6

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

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

该行动应多久执行一次; 每次渲染模板?什么时候加载?如果除了将"Hello World"打印到终端之外,它可能会变得非常混乱,即使这样也不是很安全 - 你希望你的模板文件能够打印到终端,启动核武器或窃取你的信用卡信息?

这就是为什么在所有莎士比亚模板中只允许纯值的原因.你需要这样做:

getMyHandlerR :: Handler RepHtml
getMyHandlerR = do
  muid <- maybeAuthId
  $(widgetFile "foo")
Run Code Online (Sandbox Code Playgroud)

(foo.hamlet :)

$maybe uid <- muid
  <p>Foo
$nothing
  <p>Bar
Run Code Online (Sandbox Code Playgroud)

如您所见,该maybeAuthId函数将在模板外部执行,结果在模板中匹配.这样,您可以确保在您可以确定的特定时间点检查您的会话/数据库,并确保您的模板没有注入病毒,因为您的设计师没有得到足够的报酬并且他的报复就是您.

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