我正在为Yesod工作,在我的毕业实习期间建立CMS。目前我们使用子网站(Core
)来表示管理区域,此Core
应该可以在项目之间重复使用,因此它与主站点分离并拥有自己的存储库。应该可以包含其他子网站以集成到Core
中。其他子站点都应该能够使用相同的(admin)布局。
我们使用的存储库是:
CMS核心:https://github.com/lambdacms/lambdacms-core/tree/extensions
CMS媒体扩展程序:https://github.com/lambdacms/lambdacms-media
演示Yesod大师:https://github.com/lambdacms/ponycms/tree/media
请注意,urls链接到特定的分支,这些是我目前正在使用的分支。
最初我使用函数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
,但我无法让它发挥作用。
我对Haskell和Yesod的了解是有限的,我无法找到正确方向的解决方案或指针。有没有我缺少的东西,还是有另一种方法可以接近它?
答案 0 :(得分:2)
您希望tryoutLayout
函数采用WidgetT master IO ()
类型的值,而不是WidgetT Core IO ()
,以允许您嵌入主站点路由。