Невозможно использовать безопасные маршруты типов в виджете дочернего сайта Yesod.
Я работаю над сборкой CMS поверх Yesod для моей выпускной практики. В настоящее время мы используем дочерний сайт (Core
) представлять область администратора, это Core
должен использоваться повторно между проектами, чтобы он был отделен от главного сайта и имел собственный репозиторий. Должна быть возможность включения других дочерних сайтов для интеграции в Core
, Все остальные дочерние сайты должны иметь возможность использовать ту же (администраторскую) компоновку.
Репозитории, которые мы используем:
Ядро CMS: https://github.com/lambdacms/lambdacms-core/tree/extensions
Расширение мультимедиа CMS: https://github.com/lambdacms/lambdacms-media
Демонстрация мастера Yesod: https://github.com/lambdacms/ponycms/tree/media
Обратите внимание, что здесь есть ссылки на конкретные ветки, это те ветки, которые я сейчас использую.
Изначально я использовал функцию lambdaCoreLayout
(находится в Foundation.hs), чтобы обеспечить правильную компоновку для всех обработчиков в Core
сам. Но я не смог использовать эту функцию на других сайтах. Вместо того, чтобы переписать то, что уже работало, я добавил функцию tryoutLayout
(находится в том же файле), который работает для всех дочерних сайтов и очень похож на defaultLayoutSub
(который идет с Yesod). Однако это не позволяет мне использовать getRouteToParent
в любом из обработчиков, чтобы добавить безопасные маршруты типа к виджетам.
Возьмем следующий фрагмент, например:
getAdminHomeR :: CoreHandler Html
getAdminHomeR = do
tp <- getRouteToParent
tryoutLayout [whamlet|@{tp AdminHomeR}|]
Это дает мне следующую ошибку:
Could not deduce (master ~ Core)
from the context (LambdaCmsAdmin master)
bound by the type signature for
getAdminHomeR :: LambdaCmsAdmin master =>
HandlerT Core (HandlerT master IO) Html
at LambdaCms/Core/Handler/Home.hs:17:18-33
‘master’ is a rigid type variable bound by
the type signature for
getAdminHomeR :: LambdaCmsAdmin master =>
HandlerT Core (HandlerT master IO) Html
at <no location info>
Expected type: WidgetT
Core
IO
(yesod-core-1.4.2:Yesod.Routes.Class.Route master
-> [(Text, Text)] -> Text)
Actual type: WidgetT
Core
IO
(yesod-core-1.4.2:Yesod.Routes.Class.Route
(HandlerSite (WidgetT Core IO))
-> [(Text, Text)] -> Text)
Relevant bindings include
tp :: yesod-core-1.4.2:Yesod.Routes.Class.Route Core
-> yesod-core-1.4.2:Yesod.Routes.Class.Route master
(bound at LambdaCms/Core/Handler/Home.hs:20:3)
getAdminHomeR :: HandlerT Core (HandlerT master IO) Html
(bound at LambdaCms/Core/Handler/Home.hs:19:1)
In the first argument of ‘(>>=)’, namely ‘getUrlRenderParams’
In the first argument of ‘tryoutLayout’, namely
‘((getUrlRenderParams
>>=
(\ urender_agTZ
-> (asWidgetT . toWidget)
(toHtml (\ u_agU0 -> urender_agTZ u_agU0 [] (tp AdminHomeR))))))’
Если я прав, эта ошибка говорит о том, что getRouteToParent
пытаясь вернуть функцию, которая пытается сгенерировать Route Core
вместо Route master
, Я пробовал разные места ставить tp <- getRouteToParent
но я не смог заставить его работать.
Мои собственные знания Хаскелла и Йесода ограничены, и я не смог найти решение или указатели в правильном направлении. Есть ли что-то, что я пропускаю или есть другой способ, к которому следует подходить?
1 ответ
Вы хотите, чтобы ваш tryoutLayout
функция для получения значения типа WidgetT master IO ()
не WidgetT Core IO ()
, чтобы можно было встраивать маршруты мастер сайтов.