
On Sun, Feb 13, 2011 at 12:51 PM, Dmitry Kurochkin
Hello.
I am trying to make a menu widget for a site. It would render list of menu items and mark the active one. I started with a new Menu module that exports (mainMenu :: Widget ()) function. The function gets the current route, iterates over a list of (item title, item route) list and constructs the menu. Now I can import Menu in a handler module and use ^{mainMenu} in hamlet template.
Next I tried to put the menu widget to default layout - menu should be on every page so default layout is where it belongs. Rest of the email describes problems I got.
For the record, I think this is a very good approach. Let's address specific issues below.
1. Module import loop.
I need to import the widget module in the module which defines defaultLayout, i.e. the main application module. But the widget module uses the main application module to have routes and probably other staff, hence import loop. I tried to separate foundation and route declaration from Yesod instance declaration, so that the widget module could import just routes declaration and Yesod instance could import the widget module. Turns out that does not work:
The simplest solution is to just define the mainMenu widget in the same file as the Yesod instance. Is there a reason to avoid this? It's definitely possible to split up the Yesod instance and the call to mkYesodData, but doing so requires an orphan instance. It's not a particularly *dangerous* orphan instance, but even so I think avoiding orphans is a good goal.
Attempting to interpret your app... Compile failed:
Menu.hs:20:23: Couldn't match expected type `Route m' against inferred type `TestAppRoute' NB: `Route' is a type function, and may not be injective In the first argument of `\ u[a7Kv] -> hamlet-0.7.0.2:Text.Hamlet.Quasi.urlToHamletMonad u[a7Kv] []', namely `AboutR' In a stmt of a 'do' expression: \ u[a7Kv] -> hamlet-0.7.0.2:Text.Hamlet.Quasi.urlToHamletMonad u[a7Kv] [] AboutR In the first argument of `hamlet-0.7.0.2:Text.Hamlet.Quasi.toHamletValue', namely `do { (hamlet-0.7.0.2:Text.Hamlet.Quasi.htmlToHamletMonad . preEscapedString) "