packages feed

scotty-hastache (empty) → 0.1.0

raw patch · 6 files changed

+279/−0 lines, 6 filesdep +basedep +blaze-htmldep +blaze-markupsetup-changed

Dependencies added: base, blaze-html, blaze-markup, containers, filepath, hastache, http-types, mtl, scotty, wai, warp

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2013, Daniil Frumin++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Daniil Frumin nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ examples/hastachetest.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE OverloadedStrings #-}+-- http://orbt.io/QHBm.png+module Main where++import Text.Hastache+import Web.Scotty.Trans as S+import Web.Scotty.Hastache++main :: IO ()+main = scottyH 3000 $ do+  setTemplatesDir "templates"++  get "/:word" $ do+    beam <- param "word"+    setH "action" $ MuVariable (beam :: String)+    hastache "greet.html"
+ examples/templates/greet.html view
@@ -0,0 +1,14 @@+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">+<html> <head>+<title></title>+</head>++<body>+<h1>Scotty, {{action}} me up!</h1>++++<hr>+<address></address>+<!-- hhmts start --><!-- hhmts end -->+</body> </html>
+ scotty-hastache.cabal view
@@ -0,0 +1,49 @@+name:                scotty-hastache+version:             0.1.0+homepage:            https://github.com/co-dan/scotty-hastache+bug-reports:	     https://github.com/co-dan/scotty-hastache/issues+synopsis:            Easy Mustache templating support for Scotty++description:         This library provides a small templating DSL extension+                     for Scotty via the `hastache` library.  +                     .+                     [Scotty] is a light-weighted Web framework\/router <http://hackage.haskell.org/package/scotty>+                     .+                     [Hashache] is a Haskell implementation of the Mustache templates: <http://mustache.github.io/>, <http://hackage.haskell.org/package/hastache>+                     ++license:             BSD3+license-file:        LICENSE+author:              Dan Frumin+maintainer:          difrumin@gmail.com+copyright:           (c) 2013 Dan Frumin <difrumin@gmail.com>+category:            Web+stability:           experimental+build-type:          Simple+cabal-version:       >=1.10++extra-source-files:  examples/hastachetest.hs+                     examples/templates/greet.html++library+  exposed-modules:     Web.Scotty.Hastache+  build-depends:       base            >= 4.4 && < 5,+                       blaze-html      >= 0.6.0.0,+                       blaze-markup    >= 0.5.1.0,+                       containers      >= 0.5.0.0,+                       filepath        >= 1.3.0.0,+                       hastache        >= 0.5.0,+                       http-types      >= 0.7.3.0.1,+                       mtl             >= 2.1.2,+                       scotty          >= 0.5.0,+                       wai             >= 1.3.0.1,+                       warp            >= 1.3.4.1+++  hs-source-dirs:      src+  GHC-options:         -Wall -fno-warn-orphans+  default-language:    Haskell2010++source-repository head+  type:           git+  location:       git://github.com/co-dan/scotty-hastache.git
+ src/Web/Scotty/Hastache.hs view
@@ -0,0 +1,168 @@+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE ImpredicativeTypes         #-}+{-# LANGUAGE InstanceSigs               #-}+{-# LANGUAGE OverloadedStrings          #-}+{-# LANGUAGE ScopedTypeVariables        #-}+{-# LANGUAGE TypeSynonymInstances       #-}++{- | Hastache templating for Scotty++@+\{\-\# LANGUAGE OverloadedStrings \#\-\}+module Main where++import Text.Hastache+import Web.Scotty.Trans as S+import Web.Scotty.Hastache++main :: IO ()+main = scottyH 3000 $ do+  setTemplatesDir \"templates\"+  -- ^ Setting up the director with templates+  get \"/:word\" $ do+    beam <- param \"word\"+    setH \"action\" $ MuVariable (beam :: String)+    -- ^ \"action\" will be binded to the contents of \'beam\'+    hastache \"greet.html\"+@++Given the following template:++@+\<h1\>Scotty, {{action}} me up!\<\/h1\>+@++Upon the @GET \/beam@ the result will be:++@+\<h1\>Scotty, beam me up!\<\/h1\>+@++-}+module Web.Scotty.Hastache where++import           Control.Arrow                   ((***))+import           Control.Monad.State             as State+import           Data.IORef                      (newIORef, readIORef,+                                                  writeIORef)+import qualified Data.Map                        as M+import           Data.Maybe                      (fromMaybe)+import           Data.Monoid                     (mempty)+import           Network.Wai                     (Application, Response)+import           Network.Wai.Handler.Warp        (Port)+import           System.FilePath.Posix           ((</>))+import           Text.Blaze.Html.Renderer.String as BRS+import           Text.Blaze.Html.Renderer.Utf8   as BRU+import           Text.Blaze.Internal             (Markup)+import           Text.Hastache+import           Text.Hastache.Context+import           Web.Scotty.Trans                as S++-- * Runners and types++-- | The runner to use instead of 'scotty'+scottyH :: Port -> ScottyH () -> IO ()+scottyH p s = do+    (runH, runActionToIO) <- mkHStateRunners defaultConfig+    scottyT p runH runActionToIO s++-- | The runner to use instead of 'scottyOpts'+scottyHOpts :: Options -> ScottyH () -> IO ()+scottyHOpts opts s = do+    (runH, runActionToIO) <- mkHStateRunners defaultConfig+    scottyOptsT opts runH runActionToIO s++-- | A type synonym for @ScottyT HState@+type ScottyH = ScottyT HState++-- | A type synonym for @ScottyT HState@+type ActionH = ActionT HState++-- * The DSL itself++-- ** Configuration++-- | Update the Hastache configuration as whole+setHastacheConfig :: MuConfig IO -> ScottyH ()+setHastacheConfig conf = do+  (_, tmap) <- lift State.get+  lift . State.put $ (conf, tmap)++-- | Modify the Hastache configuration as whole+modifyHastacheConfig :: (MuConfig IO -> MuConfig IO) -> ScottyH ()+modifyHastacheConfig f = lift $ State.modify (f *** id)++-- | Set the path to the directory with templates. This affects+-- how /both/ 'hastache' and the @{{> template}}@ bit searches for the+-- template files.+setTemplatesDir :: FilePath -> ScottyH ()+setTemplatesDir dir = do+  lift $ State.modify $ \(conf :: MuConfig IO, tmap) ->+      (conf { muTemplateFileDir = Just dir }, tmap)++-- | Set the default extension for template files. This affects+-- how /both/ 'hastache' and the @{{> template}}@ bit searches for the+-- template files.+setTemplateFileExt :: String -> ScottyH ()+setTemplateFileExt ext = do+  lift $ State.modify $ \(conf :: MuConfig IO, tmap) ->+      (conf { muTemplateFileExt = Just ext }, tmap)++-- ** Actions++-- | This is a function, just like 'S.html' or 'S.text'.+-- It takes a name of the template (the path is computed using the +-- information about the templates dir and template files extension) +-- and renders it using Hastache.+--+-- The variables that have been initialized using 'setH' are +-- substituted for their values, uninitialized variables are +-- considered to be empty/null.+hastache :: FilePath -> ActionT HState ()+hastache tpl = do+  ((conf :: MuConfig IO), tmap) <- lift State.get+  setHeader "Content-Type" "text/html"+  let cntx a  = fromMaybe MuNothing (M.lookup a tmap)+  let tplFile = fromMaybe "." (muTemplateFileDir conf)+              </> tpl+              ++ fromMaybe "" (muTemplateFileExt conf)+  res <- liftIO $ hastacheFile conf tplFile (mkStrContext cntx)+  raw res++-- | Set the value of a mustache variable.+setH :: String -> MuType IO -> ActionT HState ()+setH x y = do+  (conf, tmap) <- lift State.get+  lift . State.put $ (conf, M.insert x y tmap)++-- * Internals++-- | State with the Hastache config+type HState = StateT (MuConfig IO, M.Map String (MuType IO)) IO++mkHStateRunners :: MuConfig IO -> IO (forall a. HState a -> IO a, HState Response -> IO Response)+mkHStateRunners conf = do+    gstate <- newIORef undefined+    let runH m = do+            (r,(muconf,_)) <- runStateT m (conf, mempty)+            writeIORef gstate muconf+            return r+        runActionToIO m = do+            muconf <- readIORef gstate+            evalStateT m (muconf, mempty)+    return (runH, runActionToIO)++scottyHApp :: MuConfig IO -> ScottyH () -> IO Application+scottyHApp conf defs = do+    (runH, runActionToIO) <- mkHStateRunners conf+    scottyAppT runH runActionToIO defs++instance Show Markup where+  show = BRS.renderHtml++instance MuVar Markup where+  isEmpty = isEmpty . BRU.renderHtml+  toLByteString = BRU.renderHtml++