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?

+3


source to share


1 answer


You want your function to tryoutLayout

accept a type value WidgetT master IO ()

, not WidgetT Core IO ()

so that you can insert master site routes.



+2


source







All Articles