Проверить, вошел ли пользователь в шаблон Hamlet

Я хочу проверить, аутентифицирован ли пользователь, и показать ссылку «войти» или «выйти» в зависимости от состояния.

До сих пор у меня есть

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

person oh_cripes    schedule 29.07.2012    source источник


Ответы (1)


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")

(фу.гамлет:)

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

Как видите, функция maybeAuthId будет выполняться вне шаблона, а результат сопоставляется внутри шаблона. Таким образом, вы можете убедиться, что ваша сессия/база данных проверяется в определенный момент времени, который вы можете определить, и что ваш шаблон не внедряет вирус, потому что вашему дизайнеру не заплатили достаточно и он отомстил ты.

Кстати, вы можете использовать Bool, чтобы указать, вошел ли пользователь в систему, и вместо этого использовать оператор $if. Возможно, вы захотите использовать для этого функцию isJust из модуля Data.Maybe.

person dflemstr    schedule 29.07.2012
comment
Круто спасибо. Я медленно осваиваю монады и хаскелл в целом. - person oh_cripes; 02.08.2012