digestive-functors-heist 0.5.1.1 → 0.6.0.0
raw patch · 2 files changed
+123/−29 lines, 2 filesdep ~digestive-functorsPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: digestive-functors
API changes (from Hackage documentation)
+ Text.Digestive.Heist: dfInputList :: MonadIO m => View Text -> Splice m
+ Text.Digestive.Heist: dfInputSelectGroup :: Monad m => View Text -> Splice m
- Text.Digestive.Heist: bindDigestiveSplices :: Monad m => View Text -> HeistState m -> HeistState m
+ Text.Digestive.Heist: bindDigestiveSplices :: MonadIO m => View Text -> HeistState m -> HeistState m
- Text.Digestive.Heist: dfSubView :: Monad m => View Text -> Splice m
+ Text.Digestive.Heist: dfSubView :: MonadIO m => View Text -> Splice m
- Text.Digestive.Heist: digestiveSplices :: Monad m => View Text -> [(Text, Splice m)]
+ Text.Digestive.Heist: digestiveSplices :: MonadIO m => View Text -> [(Text, Splice m)]
Files
- digestive-functors-heist.cabal +2/−2
- src/Text/Digestive/Heist.hs +121/−27
digestive-functors-heist.cabal view
@@ -1,5 +1,5 @@ Name: digestive-functors-heist-Version: 0.5.1.1+Version: 0.6.0.0 Synopsis: Heist frontend for the digestive-functors library Description: Heist frontend for the digestive-functors library Homepage: http://github.com/jaspervdj/digestive-functors@@ -18,7 +18,7 @@ Build-depends: base >= 4 && < 5,- digestive-functors >= 0.5 && < 0.6,+ digestive-functors >= 0.6 && < 0.7, heist >= 0.10.2 && < 0.11, mtl >= 2, text >= 0.11 && < 0.12,
src/Text/Digestive/Heist.hs view
@@ -30,11 +30,13 @@ -- * Main splices , dfInput+ , dfInputList , dfInputText , dfInputTextArea , dfInputPassword , dfInputHidden , dfInputSelect+ , dfInputSelectGroup , dfInputRadio , dfInputCheckbox , dfInputSubmit@@ -51,6 +53,7 @@ -------------------------------------------------------------------------------- import Control.Monad (liftM, mplus)+import Control.Monad.Trans import Data.Function (on) import Data.List (unionBy) import Data.Maybe (fromMaybe)@@ -63,33 +66,36 @@ --------------------------------------------------------------------------------+import Text.Digestive.Form.List import Text.Digestive.View ---------------------------------------------------------------------------------bindDigestiveSplices :: Monad m => View Text -> HeistState m -> HeistState m+bindDigestiveSplices :: MonadIO m => View Text -> HeistState m -> HeistState m bindDigestiveSplices = bindSplices . digestiveSplices ---------------------------------------------------------------------------------digestiveSplices :: Monad m => View Text -> [(Text, Splice m)]+digestiveSplices :: MonadIO m => View Text -> [(Text, Splice m)] digestiveSplices view =- [ ("dfInput", dfInput view)- , ("dfInputText", dfInputText view)- , ("dfInputTextArea", dfInputTextArea view)- , ("dfInputPassword", dfInputPassword view)- , ("dfInputHidden", dfInputHidden view)- , ("dfInputSelect", dfInputSelect view)- , ("dfInputRadio", dfInputRadio view)- , ("dfInputCheckbox", dfInputCheckbox view)- , ("dfInputFile", dfInputFile view)- , ("dfInputSubmit", dfInputSubmit view)- , ("dfLabel", dfLabel view)- , ("dfForm", dfForm view)- , ("dfErrorList", dfErrorList view)- , ("dfChildErrorList", dfChildErrorList view)- , ("dfSubView", dfSubView view)- , ("dfIfChildErrors", dfIfChildErrors view)+ [ ("dfInput", dfInput view)+ , ("dfInputList", dfInputList view)+ , ("dfInputText", dfInputText view)+ , ("dfInputTextArea", dfInputTextArea view)+ , ("dfInputPassword", dfInputPassword view)+ , ("dfInputHidden", dfInputHidden view)+ , ("dfInputSelect", dfInputSelect view)+ , ("dfInputSelectGroup", dfInputSelectGroup view)+ , ("dfInputRadio", dfInputRadio view)+ , ("dfInputCheckbox", dfInputCheckbox view)+ , ("dfInputFile", dfInputFile view)+ , ("dfInputSubmit", dfInputSubmit view)+ , ("dfLabel", dfLabel view)+ , ("dfForm", dfForm view)+ , ("dfErrorList", dfErrorList view)+ , ("dfChildErrorList", dfChildErrorList view)+ , ("dfSubView", dfSubView view)+ , ("dfIfChildErrors", dfIfChildErrors view) ] @@ -205,18 +211,40 @@ (ref, attrs) <- getRefAttributes Nothing let ref' = absoluteRef ref view choices = fieldInputChoice ref view- children = map makeOption choices+ kids = map makeOption choices value i = ref' `mappend` "." `mappend` i makeOption (i, c, sel) = X.Element "option" (attr sel ("selected", "selected") [("value", value i)]) [X.TextNode c] - return $ makeElement "select" children $ addAttrs attrs+ return $ makeElement "select" kids $ addAttrs attrs [("id", ref'), ("name", ref')] --------------------------------------------------------------------------------+-- | Generate a select button (also known as a combo box). Example:+--+-- > <dfInputSelectGroup ref="user.sex" />+dfInputSelectGroup :: Monad m => View Text -> Splice m+dfInputSelectGroup view = do+ (ref, attrs) <- getRefAttributes Nothing+ let ref' = absoluteRef ref view+ choices = fieldInputChoiceGroup ref view+ kids = map makeGroup choices+ value i = ref' `mappend` "." `mappend` i++ makeGroup (name, options) = X.Element "optgroup"+ [("label", name)] $ map makeOption options+ makeOption (i, c, sel) = X.Element "option"+ (attr sel ("selected", "selected") [("value", value i)])+ [X.TextNode c]++ return $ makeElement "select" kids $ addAttrs attrs+ [("id", ref'), ("name", ref')]+++-------------------------------------------------------------------------------- -- | Generate a number of radio buttons. Example: -- -- > <dfInputRadio ref="user.sex" />@@ -226,7 +254,7 @@ let ref' = absoluteRef ref view choices = fieldInputChoice ref view- children = concatMap makeOption choices+ kids = concatMap makeOption choices value i = ref' `mappend` "." `mappend` i makeOption (i, c, sel) =@@ -238,7 +266,7 @@ , X.Element "label" [("for", value i)] [X.TextNode c] ] - return children+ return kids --------------------------------------------------------------------------------@@ -374,16 +402,83 @@ -- > </dfSubView> -- > -- > <dfInputTextArea ref="comment.body" />-dfSubView :: Monad m => View Text -> Splice m+dfSubView :: MonadIO m => View Text -> Splice m dfSubView view = do (ref, _) <- getRefAttributes Nothing- content <- getContent let view' = subView ref view- nodes <- localHS (bindDigestiveSplices view') $ runNodeList content+ nodes <- localHS (bindDigestiveSplices view') runChildren return nodes --------------------------------------------------------------------------------+-- | This splice allows variable length lists. It binds several attribute+-- splices providing functionality for dynamically manipulating the list. The+-- following descriptions will use the example of a form named \"foo\" with a+-- list subform named \"items\".+--+-- Splices:+-- dfListItem - This tag must surround the markup for a single list item.+-- It surrounds all of its children with a div with id \"foo.items\" and+-- class \"inputList\".+-- +-- Attribute Splices:+-- itemAttrs - Attribute you should use on div, span, etc that surrounds all+-- the markup for a single list item. This splice expands to an id of+-- \"foo.items.ix\" (where ix is the index of the current item) and a+-- class of \"inputListItem\".+-- addControl - Use this attribute on the tag you use to define a control+-- for adding elements to the list (usually a button or anchor). It adds+-- an onclick attribute that calls a javascript function addInputListItem.+-- removeControl - Use this attribute on the control for removing individual+-- items. It adds an onclick attribute that calls removeInputListItem.+dfInputList :: MonadIO m => View Text -> Splice m+dfInputList view = do+ (ref, _) <- getRefAttributes Nothing+ let listRef = absoluteRef ref view+ listAttrs =+ [ ("id", listRef)+ , ("class", "inputList")+ ]+ addControl _ = return+ [ ("onclick", T.concat [ "addInputListItem(this, '"+ , listRef+ , "'); return false;"] ) ]+ removeControl _ = return+ [ ("onclick", T.concat [ "removeInputListItem(this, '"+ , listRef+ , "'); return false;"] ) ]+ itemAttrs v _ = return+ [ ("id", T.concat [listRef, ".", last $ "0" : viewContext v])+ , ("class", T.append listRef ".inputListItem")+ ]+ templateAttrs v _ = return+ [ ("id", T.concat [listRef, ".", last $ "-1" : viewContext v])+ , ("class", T.append listRef ".inputListTemplate")+ , ("style", "display: none;")+ ]+ items = listSubViews ref view+ f attrs v = localHS (bindAttributeSplices [("itemAttrs", attrs v)] .+ bindDigestiveSplices v) runChildren+ dfListItem = do+ template <- f templateAttrs (makeListSubView ref (-1) view)+ res <- mapSplices (f itemAttrs) items+ return $ template ++ res+ attrSplices = [ ("addControl", addControl)+ , ("removeControl", removeControl)+ ]+ nodes <- localHS (bindSplices [("dfListItem", dfListItem)] .+ bindAttributeSplices attrSplices) runChildren+ let indices = [X.Element "input"+ [ ("type", "hidden")+ , ("name", T.intercalate "." [listRef, indicesRef])+ , ("value", T.intercalate "," $ map+ (last . ("0":) . viewContext) items)+ ] []+ ]+ return [X.Element "div" listAttrs (indices ++ nodes)]+++-------------------------------------------------------------------------------- -- | Render some content only if there are any errors. This is useful for markup -- purposes. --@@ -395,7 +490,6 @@ dfIfChildErrors :: Monad m => View v -> Splice m dfIfChildErrors view = do (ref, _) <- getRefAttributes $ Just ""- content <- getContent if null (childErrors ref view) then return []- else runNodeList content+ else runChildren