[more updates to JMacro section Jeremy Shaw **20110523202300 Ignore-this: 974cf34554a47de7338921a5d10e83ec ] hunk ./JMacro.markdown.lhs 7 -JMacro is a -library that makes it easy to generate JavaScript in Haskell. This is -useful even if you are just trying to add a little bit of JavaScript code -to your HTML templates. +

To use JMacro with happstack and hsx, you should install the + hsx-jmacro and happstack-jmacro packages. You will also need to be sure that your version of happstack-hsp is >= 6.1.0.

hunk ./JMacro.markdown.lhs 10 -To use JMacro with happstack and hsx, you should install the -hsx-jmacro and happstack-jmacro packages. You will also need to be sure that your version of happstack-hsp is >= 6.1.0. +JMacro is a library that makes it easy to include javascript in your templates. hunk ./JMacro.markdown.lhs 29 -The happstack-jmacro library makes it easy to use JMacro with Happstack and HSP. +The hsx-jmacro and happstack-jmacro libraries makes it easy to use JMacro with Happstack and HSP. hunk ./JMacro.markdown.lhs 31 -The following should get you started. +The following examples demonstrate the basics of JMacro and how it interfaces with HSX and Happstack. The examples are intended to demonstrate what is possible with JMacro. The examples are not intended to demonstrate good javascript practices. For example, many developers frown on the use of the onclick attribute in html, or having <script> tags in the <body>. hunk ./JMacro.markdown.lhs 37 -So, we need to enable the QuasiQuotes LANGUAGE extension: +QuasiQuotes can be enabled via the LANGUAGE extension: + hunk ./JMacro.markdown.lhs 55 -Next we have a boatload if imports: +Next we have a boatload of imports. Not all of these are required to use JMacro. Many are just used for the demos. hunk ./JMacro.markdown.lhs 111 + +

JMacro in a <script> tag

+ hunk ./JMacro.markdown.lhs 139 -We can also use jmacro inside html attributes, such as onclick. +

JMacro in an HTML attribute (onclick, etc)

+ +We can also use JMacro inside html attributes, such as onclick. hunk ./JMacro.markdown.lhs 152 -onclick handler. It is taken care of for us automatically! The code automatically get's escaped as: +onclick handler. It is taken care of for us automatically! The code is automatically escaped as: hunk ./JMacro.markdown.lhs 158 -According to the Automatice escaping of </ + +According to the HTML Hygienic Variable Names + +So far, using HSP with JMacro looks almost exactly like using HSP with hunk ./JMacro.markdown.lhs 190 -the mental tax for using jmacro over straight JavaScript is very low. +the mental tax for using JMacro over straight JavaScript is very low. hunk ./JMacro.markdown.lhs 219 -But, jmacro automatically renames the variables for us so that the +But, JMacro automatically renames the variables for us so that the hunk ./JMacro.markdown.lhs 236 +

Non-Hygienic Variable Names

+ hunk ./JMacro.markdown.lhs 259 +> clickMe2Init :: JStat +> clickMe2Init = +> [$jmacro| var !clickCnt = 0; |]; +> hunk ./JMacro.markdown.lhs 270 -> var !clickCnt = 0; hunk ./JMacro.markdown.lhs 278 -> toResponse <$> defaultTemplate "Hygienic Naming" () +> toResponse <$> defaultTemplate "Hygienic Naming" +> <% clickMe2Init %> hunk ./JMacro.markdown.lhs 289 -We can also splice Haskell values into the JavaScript code by using `( )`. In the following example, the `onclick` action for the <button> calls `revealFortune()`. The argument to revealForture is the `String` returned by evaluating the Haskell expression `fortunes !! n`. +

Declaring Functions

+ +Hygienic naming affects function declarations as well. If we want to define a function in <head>, but call the function from the <body>, then we need to disable hygienic naming. We can do that using the ! trick again: + +
+#ifdef HsColour +> function !hello(noun) { alert('hello ' + noun); } +#endif +
+ +JMacro also has some syntax extensions for declaring functions. We can +create an anonymous function using Haskell-like syntax assign it to a variable: + +
+#ifdef HsColour +> var !helloAgain = \noun ->alert('hello again, ' + noun); +#endif +
+ +Another option is to use the ML-like fun keyword to declare a function. When using fun we do not need the !. + +
+#ifdef HsColour +> fun goodbye noun { alert('goodbye ' + noun); } +#endif +
+ +Or we can do both: + +
+#ifdef HsColour +> fun goodbyeAgain noun -> alert('goodbye again, ' + noun); +#endif +
+ +Here they all are in an example: + +
+ +> functionNames :: JMacroPart Response +> functionNames = +> toResponse <$> defaultTemplate "Function Names" +> <% [$jmacro| +> function !hello(noun) { alert('hello, ' + noun); } +> var !helloAgain = \noun ->alert('hello again, ' + noun); +> fun goodbye noun { alert('goodbye ' + noun); } +> fun goodbyeAgain noun -> alert('goodbye again, ' + noun); +> |] +> %> +> <%> +> +> +> +> +> +> + +
+ +

Splicing Haskell Values into JavaScript (Antiquotation)

+ +We can also splice Haskell values into the JavaScript code by using `( )`. In the following example, the `onclick` action for the <button> calls `revealFortune()`. The argument to `revealForture` is the `String` returned by evaluating the Haskell expression `fortunes !! n`. hunk ./JMacro.markdown.lhs 356 -> do let fortunes = ["Your will be cursed to write java for the rest of your days." +> do let fortunes = ["You will be cursed to write Java for the rest of your days." hunk ./JMacro.markdown.lhs 363 -> function !revealFortune(fortune) +> fun revealFortune fortune hunk ./JMacro.markdown.lhs 383 +

Using ToJExpr to convert Haskell values to JavaScript

+ hunk ./JMacro.markdown.lhs 431 -For `Fahrenheit`, we were actually able to derive the `ToJExpr` instance automatically (aka, `deriving (ToJExpr)`), because it a `newtype` wrapper around `Double` which already has a `ToExpr` instance. +For `Fahrenheit`, we were actually able to derive the `ToJExpr` instance automatically (aka, `deriving (ToJExpr)`), because it is a `newtype` wrapper around `Double` which already has a `ToExpr` instance. hunk ./JMacro.markdown.lhs 484 -So far we have use jmacro to generate JavaScript that is embedded in HTML. We can also use it to create standalone JavaScript. + +

Using JMacro in external .js scripts

+ +So far we have used JMacro to generate JavaScript that is embedded in HTML. We can also use it to create standalone JavaScript. hunk ./JMacro.markdown.lhs 495 -> function !greet(noun) +> fun greet noun hunk ./JMacro.markdown.lhs 503 -(Note that we use the bang synaxt when declaring `greet` so that it will not be renamed.) Then we have a server part with two sub-parts: + +Then we have a server part with two sub-parts: + hunk ./JMacro.markdown.lhs 527 -> +> hunk ./JMacro.markdown.lhs 534 -Here is a little page that links to all the jmacro demos: +

Links to demos

+ +Here is a little page that links to all the JMacro demos: hunk ./JMacro.markdown.lhs 544 ->
  • Hello, JMacro
  • ->
  • Hello, Attr
  • ->
  • Hello, End Tag
  • ->
  • ClickMe
  • ->
  • ClickMe2
  • ->
  • Weather
  • ->
  • Fortune
  • ->
  • External
  • +>
  • Hello, JMacro
  • +>
  • Hello, Attr
  • +>
  • Hello, End Tag
  • +>
  • ClickMe
  • +>
  • ClickMe2
  • +>
  • Function Names
  • +>
  • Fortune
  • +>
  • Weather
  • +>
  • External
  • hunk ./JMacro.markdown.lhs 562 -> msum [ dir "hello" $ helloJMacro -> , dir "attr" $ helloAttr -> , dir "endTag" $ helloEndTag -> , dir "clickMe" $ clickPart -> , dir "clickMe2" $ clickPart2 -> , dir "weather" $ weatherPart -> , dir "fortune" $ fortunePart +> msum [ dir "hello" $ helloJMacro +> , dir "attr" $ helloAttr +> , dir "endTag" $ helloEndTag +> , dir "clickMe" $ clickPart +> , dir "clickMe2" $ clickPart2 +> , dir "functions" $ functionNames +> , dir "fortune" $ fortunePart +> , dir "weather" $ weatherPart hunk ./JMacro.markdown.lhs 579 +

    Alternative IntegerSupply instance

    + hunk ./JMacro.markdown.lhs 593 -This should be safe as long as you have less than 1024 different jmacro blocks on a single page. +This should be safe as long as you have less than 1024 different JMacro blocks on a single page. hunk ./JMacro.markdown.lhs 597 -For more information on using JMacro I recommend reading this wiki page and the tutorial at the top of Language.Javascript.JMacro. +For more information on using JMacro I recommend reading this wiki page and the tutorial at the top of Language.Javascript.JMacro. The documentation is this tutorial has covered the basics of JMacro, but not everything! hunk ./theme.css 186 -.hs-comment, .hs-comment a { color: Red;} +.hs-comment, .hs-comment a { color: FireBrick;} hunk ./theme.css 195 -.hs-sel { color: Red; } -.hs-cpp { color: Red; } +.hs-sel { color: FireBrick; } +.hs-cpp { color: FireBrick; }