Haskell / Julius templates - can't splice variables

192 views Asked by At

I think there's something i don't understand about how splicing in julius works, none of the built in types will splice. The only way I can get code to compile is with rawJS.

For example:

import Prelude.Unicode
import Text.Julius

import Text.Shakespeare    -- not sure if this is needed
import Text.Shakespeare.Text    -- not sure if this is needed
...


test = renderJavascript $ jsCode (⊥)
  where
    yval = rawJS $ show (3 ∷ Int) -- works
    -- yval = show (3 ∷ Int) -- no instance of toJavascript
    -- yval = 3 ∷ Int -- no instance of toJavascript
    jsCode = [js|
      var y = #{yval};
      |]

FWIW I'm not using yesod, just the julius templating part of the library, but that shouldn't matter here I think.

If I try to splice the Int itself, I get an error like:

No instance for (ToJavascript Int)
  arising from a use of ‘toJavascript’
In the expression: toJavascript yval
In the first argument of ‘mconcat’, namely
  ‘[Javascript
      ((Data.Text.Internal.Builder.fromText . pack')
         "\n\
         \      var y = "),
    toJavascript yval,
    Javascript
      ((Data.Text.Internal.Builder.fromText . pack')
         ";\n\
         \      ")]’
In the expression:
  mconcat
    [Javascript
       ((Data.Text.Internal.Builder.fromText . pack')
          "\n\
          \      var y = "),
     toJavascript yval,
     Javascript
       ((Data.Text.Internal.Builder.fromText . pack')
          ";\n\
          \      ")]
1

There are 1 answers

0
leftaroundabout On

As the documentation can tell you, the ToJavascript class only has instances of

  • Bool
  • RawJavaScript
  • and JSON Values. These are what you want to use.


import Data.Aeson    

test = renderJavascript $ jsCode (⊥)
  where
    yval = Number 3
    jsCode = [js|
      var y = #{yval};
      |]

...or, if yint = 3 :: Int is given, yval = Number $ fromIntegral yint. Both uses the fact that the Number constructor uses a Num type (so you can use numerical literals as well as standard conversion functions), namely Scientific.

Why, if there's a class ToJavascript anyway, they don't also offer at least an instance for Int, I have no idea.