Unable to use safe type routes in Yesod child node widgets
I am working on building a CMS on top of Yesod for my internship. We are currently using a subsite ( Core
) to represent the admin area, this one Core
needs to be reused between projects, so it is separate from the main site and has its own repository. It should be possible to include other sub-sites for integration into Core
. All other subsites must be able to use the same (administrative) layout.
The repos we use are:
CMS Core: https://github.com/lambdacms/lambdacms-core/tree/extensions
CMS Media Extension: https://github.com/lambdacms/lambdacms-media
Yesod Demo Master: https: //github.com/lambdacms/ponycms/tree/media
Note that the urls are linked to specific branches, these are the branches that I am currently using.
I originally used a function lambdaCoreLayout
(found in Foundation.hs ) to provide the correct layout for all handlers within Core
, but I couldn't use this function in other sub sites. Rather than rewrite what already worked, I added a function tryoutLayout
(found in the same file) that works for all sub-sites and is very similar to defaultLayoutSub
(that ships with Yesod). However, this prevents me from using getRouteToParent
in any of the handlers to add type safe routes to widgets.
take the following snippet for example:
getAdminHomeR :: CoreHandler Html
getAdminHomeR = do
tp <- getRouteToParent
tryoutLayout [whamlet|@{tp AdminHomeR}|]
This gives me the following error:
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))))))’
If I am correct, this error suggests that it is getRouteToParent
trying to return a function that is trying to generate Route Core
instead Route master
. I've tried different places to put it tp <- getRouteToParent
, but I couldn't get it to work.
My own knowledge of Haskell and Yesod is limited and I haven't been able to find a solution or pointers in the right direction. Is there something I am missing, or is there another way that this needs to be approached?
source to share