* updated elm-yesod for URL interpolation

- An instance for ElmSource (urlRenderFn, url -> Elm) has been added.
- elm-yesod's elmWidget function now supports URL interpolation, it
returns a widget in the GHandler monad and needs to be used
differently. The elm-yesod example has not yet been updated.
This commit is contained in:
Vincent Ambo 2012-05-30 21:17:58 +02:00
parent aab25b8356
commit 3d4bbeb84c
2 changed files with 36 additions and 16 deletions

View File

@ -1,4 +1,4 @@
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE QuasiQuotes, TypeSynonymInstances #-}
{- | This module provides a function for compiling Elm source code into a Yesod widget.
In order to use this with your Yesod app, you need to define a defaultLayout like
function that embeds the elm-min.js file /in the <head> tag/.
@ -15,32 +15,46 @@
A full example implementation is provided in the examples folder of the Elm github repository.
-}
module Language.Elm.Yesod (elmWidget) where
module Language.Elm.Yesod (
elmWidget
, ElmUrl) where
import Control.Monad (liftM)
import Text.Blaze (preEscapedToMarkup)
import Text.Julius
import Yesod.Widget (toWidgetHead, toWidgetBody, GWidget)
import Yesod.Core
import Yesod.Handler
import Yesod.Widget
import Language.Elm
import Language.Elm.Quasi
import qualified Data.Text as TS
import qualified Data.Text.Lazy as TL
-- |toWidget takes some Elm code in String format and produces a widget. Usage example:
--
-- > toWidget [elmFile|elm-source/somePage.elm|]
elmWidget :: ElmSource a
=> a -- ^ The Elm source code
-> GWidget sub master ()
elmWidget source =
let (html, css, js) = toParts source in
instance ElmSource (ElmUrl url) where
toHtml = undefined
toParts = undefined
elmWidget :: ElmUrl (Route master) -- ^ Elm source code
-> GHandler sub master (GWidget sub master())
elmWidget source = do
urlF <- getUrlRenderParams
return $ mkElmWidget source urlF
mkElmWidget :: ElmUrl (Route master) -- ^ Elm source code
-> RenderFn (Route master) -- ^ URL rendering function
-> GWidget sub master ()
mkElmWidget source urlFn =
let (html, css, js) = toParts (urlFn, source) in
do toWidgetHead css
toWidgetHead [julius| #{js} |]
toWidgetBody html
-- | Return type of template-reading functions.
type ElmUrl url = (url -> [(TS.Text, TS.Text)] -> TS.Text) -> Elm
-- | render with route interpolation
renderElmUrl :: (url -> [(TS.Text, TS.Text)] -> TS.Text) -> ElmUrl url -> TL.Text
renderElmUrl r s = renderElm $ s r
-- | Readability synonym for render function
type RenderFn url = (url -> [(TS.Text, TS.Text)] -> TS.Text)

View File

@ -43,9 +43,15 @@ instance ElmSource TL.Text where
toParts = toPartsHelper . TL.unpack
toHtml elmL title = generateHtml elmL title . TL.unpack
-- | (urlRenderFn, urlRenderFn -> Elm)
instance ElmSource (t, t -> Elm) where
toParts (f, s) = toPartsHelper $ TL.unpack $ renderElm $ s f
toHtml elmL title (f, s) = generateHtml elmL title $ TL.unpack $ renderElm $ s f
-- | to be used without URL interpolation
instance ElmSource (t -> Elm) where
toParts s = toPartsHelper $ TL.unpack $ renderElm $ s undefined
toHtml elmL title s = generateHtml elmL title $ TL.unpack $ renderElm $ s undefined
toParts s = toPartsHelper $ TL.unpack $ renderElm $ s undefined
toHtml l t s = generateHtml l t $ TL.unpack $ renderElm $ s undefined
-- build helper to avoid boilerplate repetition