servant-ede 0.5.1 → 0.6
raw patch · 3 files changed
+64/−26 lines, 3 filesdep ~aesondep ~basedep ~bytestring
Dependency ranges changed: aeson, base, bytestring, ede, either, filepath, http-media, http-types, semigroups, servant, text, transformers, unordered-containers, vector, warp, xss-sanitize
Files
- example/example.hs +22/−1
- servant-ede.cabal +21/−19
- src/Servant/EDE.hs +21/−6
example/example.hs view
@@ -9,6 +9,9 @@ import Network.Wai.Handler.Warp import Servant import Servant.EDE+import Text.EDE.Filters ((@:),Term)+import qualified Data.HashMap.Strict as Map+import Data.Text (Text, chunksOf) -- * Using 'Tpl' for rendering CSS templates @@ -47,9 +50,12 @@ api :: Proxy API api = Proxy +filters :: [(Text,Term)]+filters = ["toChars" @: (chunksOf 1)]+ main :: IO () main = do- loadTemplates api "example"+ loadTemplates api filters "example" run 8082 (serve api $ styleServer :<|> userServer) -- You can now head to:@@ -58,6 +64,21 @@ -- http://localhost:8082/style.css -- to see 'HTML' and 'Tpl' + 'CSS' in action, -- respectively.+--+-- Example output:+--+-- curl -i -H 'Accept: text/html' http://localhost:8082/user+-- HTTP/1.1 200 OK+-- Transfer-Encoding: chunked+-- Date: Thu, 15 Sep 2016 19:41:25 GMT+-- Server: Warp/3.2.8+-- Content-Type: text/html;charset=utf-8+--+-- <ul>+-- <li><strong>Name</strong>: lambdabot</li>+-- <li><strong>Age</strong>: 35</li>+-- <li><strong>Chunked Name</strong>: ["l","a","m","b","d","a","b","o","t"]</li>+-- </ul> -- -- Feel free to tweak the content of the template files -- as well as the 'User' and 'CSSData' values in this program
servant-ede.cabal view
@@ -1,5 +1,5 @@ name: servant-ede-version: 0.5.1+version: 0.6 synopsis: Combinators for rendering EDE templates in servant web applications description: Combinators for rendering EDE templates in servant web applications.@@ -11,7 +11,7 @@ license-file: LICENSE author: Alp Mestanogullari maintainer: alpmestan@gmail.com-copyright: 2015 Alp Mestanogullari+copyright: 2015-2016 Alp Mestanogullari category: Web build-type: Simple extra-source-files: README.md@@ -29,23 +29,23 @@ , Servant.EDE.Internal.Validate build-depends:- aeson >= 0.8 && <0.10+ aeson , base >=4.7 && <5- , bytestring >= 0.10 && <0.11- , filepath >= 1.2 && <1.5- , ede >= 0.2 && <0.3- , either >= 4.0 && <4.5- , http-media >= 0.6 && <0.7- , http-types >= 0.8 && <0.9- , semigroups >= 0.16 && <0.17- , servant >= 0.4 && <0.6- , text >= 1.0 && <1.3- , transformers >= 0.4 && <0.5- , unordered-containers >= 0.2 && <0.3- , vector >= 0.9 && <0.11- , xss-sanitize >= 0.3 && <0.4+ , bytestring+ , filepath+ , ede+ , either+ , http-media+ , http-types+ , semigroups+ , servant+ , text+ , transformers+ , unordered-containers+ , vector+ , xss-sanitize - ghc-options: -O2 -Wall+ ghc-options: -Wall hs-source-dirs: src default-language: Haskell2010 @@ -55,9 +55,11 @@ hs-source-dirs: example default-language: Haskell2010 build-depends:- base >= 4.7 && <5+ base , ede , http-media , servant-server , servant-ede- , warp >= 3.0+ , text+ , unordered-containers+ , warp
src/Servant/EDE.hs view
@@ -55,7 +55,7 @@ import Control.Monad.IO.Class import Data.Aeson (Object, Value(..)) import Data.Foldable (fold)-import Data.HashMap.Strict (HashMap, (!))+import Data.HashMap.Strict (HashMap, (!),fromList) import Data.Proxy import Data.Semigroup import Data.Text (Text)@@ -69,11 +69,13 @@ import System.FilePath import System.IO.Unsafe import Text.EDE+import Text.EDE.Filters (Term) import Text.HTML.SanitizeXSS import qualified Data.HashMap.Strict as HM import qualified Data.Vector as V +type Filter = (Text,Term) -- | This function initializes a global -- template store (i.e a 'Templates' value) and fills it with -- the resulting compiled templates if all of them are compiled@@ -95,14 +97,17 @@ -- compiled template store, if successfully compiled. loadTemplates :: (Reify (TemplateFiles api), Applicative m, MonadIO m) => Proxy api+ -> [Filter] -- ^ list of (Text,Term) pairs. Pass [] to use just the standard library -> FilePath -- ^ root directory for the templates -> m Errors-loadTemplates proxy dir = do+loadTemplates proxy fpairs dir = do+ let flts = fromList fpairs res <- loadTemplates' proxy dir case res of Left errs -> return errs Right tpls -> do- liftIO $ putMVar __template_store tpls+ let tplfs = TemplatesAndFilters tpls flts+ liftIO $ putMVar __template_store tplfs return [] loadTemplates' :: (Reify (TemplateFiles api), Applicative m, MonadIO m)@@ -190,13 +195,16 @@ instance (KnownSymbol file, Accept ct, ToObject a) => MimeRender (Tpl ct file) a where mimeRender _ val = encodeUtf8 . result (error . show) id $- render templ (toObject val)+ renderWith flts templ (toObject val) where templ = tmap ! filename filename = symbolVal (Proxy :: Proxy file)- tmap = templateMap $ unsafePerformIO (readMVar __template_store)+ tmplfs = unsafePerformIO (readMVar __template_store)+ tmap = templateMap $ _templates tmplfs+ flts = _filters tmplfs -__template_store :: MVar Templates++__template_store :: MVar TemplatesAndFilters __template_store = unsafePerformIO newEmptyMVar -- | 'HTML' content type, but more than just that.@@ -319,6 +327,13 @@ mempty = Templates mempty a `mappend` b = a <> b++-- A data type that holds both the compiled templates and+-- any passed-in custom filters+data TemplatesAndFilters = TemplatesAndFilters {+ _templates :: Templates+ , _filters :: HashMap Text Term+ } tpl :: FilePath -> Template -> Templates tpl fp t = Templates $ HM.singleton fp t