5

I was using QuasiQuotations in Yesod, and everything worked fine. BUT my file became very large and not nice to look at. Also, my TextEditor does not highlight this syntax correctly. That is why is split my files like so:

getHomeR :: Handler Html
getHomeR = do
    webSockets chatApp
    defaultLayout $ do
        $(luciusFile "templates/chat.lucius")
        $(juliusFile "templates/chat.julius")
        $(hamletFile "templates/chat.hamlet")

If this is wrong, please do tell. Doing runghc myFile.hs throws many errors like this:

chat_new.hs:115:9:
    Couldn't match expected type ‘t0 -> Css’
                with actual type ‘WidgetT App IO a0’
    The lambda expression ‘\ _render_ajFK
                             -> (shakespeare-2.0.7:Text.Css.CssNoWhitespace . (foldr ($) ...))
                                  ...’
    has one argument,
    but its type ‘WidgetT App IO a0’ has none
    In a stmt of a 'do' block:
      \ _render_ajFK
      ...

And this.

chat_new.hs:116:9:
    Couldn't match type ‘(url0 -> [(Text, Text)] -> Text)
                         -> Javascript’
                   with ‘WidgetT App IO a1’
    Expected type: WidgetT App IO a1
      Actual type: JavascriptUrl url0
    Probable cause: ‘asJavascriptUrl’ is applied to too few arguments
    ...

And also one for the HTML (Hamlet).

Thus, one per template.

Divide by Zero
  • 1,343
  • 1
  • 14
  • 37
  • Try compiling or interpreting with the flag `-ddump-splices` - it will print code generated by TH (it seems the errors are in the generated code). Potentially the `do` is breaking it? Try without it. – user2407038 Mar 06 '16 at 20:26
  • 1
    Your code looks OK. Try using `$(widgetFile "chat")` instead of three separate calls. – arrowd Mar 07 '16 at 07:53
  • 1
    @arrowd i have tried doing it at first. It gives a "not in scope:" error. Do i have to import widgetfile? And where exactly do i have to call it? – Divide by Zero Mar 07 '16 at 07:59
  • @Spacemoose `widgetFile` is usually created when you scaffold your project with `yesod init`. If you created it by hand, then you need to use `widgetFileReload`/`widgetFileNoReload` from `Yesod.Default.Util`. Use it inside your do-block in place of those three calls. – arrowd Mar 07 '16 at 08:54
  • @arrowd i used this : `$(widgetFileNoReload "chat")` Got the following error: Couldn't match type ‘FilePath -> Q Exp’ with ‘Q Exp’ Expected type: ExpQ Actual type: FilePath -> Q Exp – Divide by Zero Mar 07 '16 at 09:02
  • @arrowd `widgetFileReload / widgetfileNoReload` takes two arguments. it seems i have to edit WidgetFileSettings in my Settings.hs. Do i have to somehow import this setting? How does it have to look? – Divide by Zero Mar 07 '16 at 09:10
  • 1
    Ah, right. Use `(def :: WidgetFileSettings)` as its first argument. It is defined in `Data.Default`. – arrowd Mar 07 '16 at 09:14
  • @arrowd this is actually working!!! Thank you so much Mr.Arrow ! – Divide by Zero Mar 07 '16 at 09:48

1 Answers1

2

It seems that hamletFile and others treat templates as self-contained, while yours are referencing something from each other. You can play with order of *File calls, or use widgetFile* from Yesod.Default.Util module:

$(widgetFileNoReload def "chat")

The Reload variant is useful for development - it would make yesod devel to watch for file changes and reload them.

arrowd
  • 33,231
  • 8
  • 79
  • 110