2012-07-29 67 views
2

我想测试用户是否已通过身份验证并显示“登录”或“注销”链接,具体取决于状态。测试用户是否已登录哈姆雷特模板

到目前为止,我有

$maybe muid <- maybeAuthId 
    <a [email protected]{AuthR LogoutR} >Logout 
$nothing 
    <a [email protected]{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' 

回答

6

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

$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功能将被模板外执行,并将结果内匹配模板。这样,您可以确保您的会话/数据库在您可以确定的特定时间点进行检查,并且您的模板不会注入病毒,因为您的设计师没有获得足够的报酬并对他进行报复您。

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

+0

很酷的谢谢。一般来说,我慢慢获得monad和haskell的窍门。 – 2012-08-02 16:01:32