yesod-paginator 0.1.1 → 0.2
raw patch · 2 files changed
+65/−57 lines, 2 filesdep +transformersPVP ok
version bump matches the API change (PVP)
Dependencies added: transformers
API changes (from Hackage documentation)
- Yesod.Paginator: selectPaginated :: (YesodPersistBackend m ~ PersistEntityBackend v, YesodPersist m, PersistEntity v, PersistQuery (PersistEntityBackend v) (GHandler s m)) => Int -> [Filter v] -> [SelectOpt v] -> GHandler s m ([Entity v], GWidget s m ())
+ Yesod.Paginator: selectPaginated :: (MonadTrans (PersistEntityBackend v), PersistEntity v, PersistQuery (PersistEntityBackend v) (GHandler s m)) => Int -> [Filter v] -> [SelectOpt v] -> PersistEntityBackend v (GHandler s m) ([Entity v], GWidget s1 m1 ())
Files
- Yesod/Paginator.hs +63/−56
- yesod-paginator.cabal +2/−1
Yesod/Paginator.hs view
@@ -26,9 +26,11 @@ , paginationWidget ) where -import Yesod-import Database.Persist.Store (Entity)-import Data.Text (Text)+import Yesod -- TODO: minimal deps+import Control.Monad (when)+import Control.Monad.Trans.Class (MonadTrans)+import Data.Text (Text)+import Data.Maybe (fromMaybe) import qualified Data.Text as T -- | Paginate an existing list of items.@@ -51,11 +53,10 @@ -> [a] -- ^ complete list of items -> GHandler s m ([a], GWidget s m ()) paginate per items = do- let tot = length items-- p <- getCurrentPage tot+ p <- getCurrentPage - let xs = take per $ drop ((p - 1) * per) items+ let tot = length items+ let xs = take per $ drop ((p - 1) * per) items return (xs, paginationWidget p per tot) @@ -63,7 +64,7 @@ -- -- > getSomeRoute something = do -- > -- note: things is [Entity val] just like selectList returns--- > (things, widget) <- selectPaginated 10 [SomeThing ==. something] []+-- > (things, widget) <- runDB $ selectPaginated 10 [SomeThing ==. something] [] -- > -- > defaultLayout $ do -- > [whamlet|@@ -74,17 +75,15 @@ -- > ^{widget} -- > |] ---selectPaginated :: ( YesodPersistBackend m ~ PersistEntityBackend v- , YesodPersist m+selectPaginated :: ( MonadTrans (PersistEntityBackend v) , PersistEntity v- , PersistQuery (PersistEntityBackend v) (GHandler s m)- )- => Int -> [Filter v] -> [SelectOpt v]- -> GHandler s m ([Entity v], GWidget s m ())+ , PersistQuery (PersistEntityBackend v) (GHandler s m))+ => Int-> [Filter v] -> [SelectOpt v]+ -> PersistEntityBackend v (GHandler s m) ([Entity v], GWidget s1 m1 ()) selectPaginated per filters selectOpts = do- tot <- runDB $ count filters- p <- getCurrentPage tot- xs <- runDB $ selectList filters (selectOpts ++ [OffsetBy ((p-1)*per), LimitTo per])+ p <- lift getCurrentPage+ tot <- count filters+ xs <- selectList filters (selectOpts ++ [OffsetBy ((p-1)*per), LimitTo per]) return (xs, paginationWidget p per tot) @@ -95,58 +94,52 @@ -> Int -- ^ total number of items -> GWidget s m () paginationWidget page per tot = do+ -- total / per + 1 for any remainder let pages = (\(n, r) -> n + (min r 1)) $ tot `divMod` per - if pages <= 1- then return ()- else do- let prev = [1 ..(page-1)]- let next = [(page+1)..pages ]+ when (pages > 1) $ do+ let prev = [1 ..(page-1)]+ let next = [(page+1)..pages ] - let lim = 9 -- don't show more than nine links on either side- let prev' = if length prev > lim then drop ((length prev) - lim) prev else prev- let next' = if length next > lim then take lim next else next+ let lim = 9 -- don't show more than nine links on either side+ let prev' = if length prev > lim then drop ((length prev) - lim) prev else prev+ let next' = if length next > lim then take lim next else next - curParams <- lift $ fmap reqGetParams getRequest+ curParams <- lift $ fmap reqGetParams getRequest - [whamlet|- <ul>- <li .prev :null prev:.disabled>- ^{linkTo curParams (page - 1) "← Previous"}+ [whamlet|+ <ul>+ ^{linkToDisabled (null prev) curParams (page - 1) "← Previous"} - $if (/=) prev prev'- <li>^{linkTo curParams 1 "1"}- <li>...+ $if (/=) prev prev'+ <li>^{linkTo curParams 1 "1"}+ <li>... - $forall p <- prev'- <li>^{linkTo curParams p (show p)}+ $forall p <- prev'+ <li>^{linkTo curParams p (show p)} - <li .active>- <a href="#">#{show page}+ <li .active>+ <a>#{show page} - $forall n <- next'- <li>^{linkTo curParams n (show n)}+ $forall n <- next'+ <li>^{linkTo curParams n (show n)} - $if (/=) next next'- <li>...- <li>^{linkTo curParams tot (show tot)}+ $if (/=) next next'+ <li>...+ <li>^{linkTo curParams tot (show tot)} - <li .next :null next:.disabled>- ^{linkTo curParams (page + 1) "Next →"}- |]+ ^{linkToDisabled (null next) curParams (page + 1) "Next →"}+ |] -getCurrentPage :: Int -> GHandler s m Int-getCurrentPage tot = do- mp <- lookupGetParam "p"- return $- case mp of- Nothing -> 1- Just "" -> 1- Just p ->- case readIntegral $ T.unpack p of- Just i -> if i > tot then tot else i- _ -> 1+-- | looks up the \"p\" GET param and converts it to an Int. returns a+-- default of 1 when conversion fails.+getCurrentPage :: GHandler s m Int+getCurrentPage = fmap (fromMaybe 1 . go) $ lookupGetParam "p" + where+ go :: Maybe Text -> Maybe Int+ go mp = readIntegral . T.unpack =<< mp+ updateGetParam :: [(Text,Text)] -> (Text,Text) -> Text updateGetParam getParams (p, n) = (T.cons '?') . T.intercalate "&" . map (\(k,v) -> k `T.append` "=" `T.append` v)@@ -159,3 +152,17 @@ [whamlet| <a href="#{updateGetParam params param}">#{txt} |]++-- | Similiar, but used for Previous/Next so that there's no href when+-- disabled+linkToDisabled :: Bool -- ^ disabled?+ -> [(Text,Text)] -> Int -> String -> GWidget s m ()+linkToDisabled True _ _ txt = [whamlet|+ <li .prev .disabled>+ <a>#{txt}+ |]++linkToDisabled _ params pg txt = [whamlet|+ <li .prev>+ ^{linkTo params pg txt}+ |]
yesod-paginator.cabal view
@@ -1,5 +1,5 @@ name: yesod-paginator-version: 0.1.1+version: 0.2 synopsis: A pagination approach for yesod description: Paginate a list showing a per-item widget and links to other pages homepage: http://github.com/pbrisbin/yesod-paginator@@ -18,6 +18,7 @@ , text >= 0.11 && < 0.12 , yesod >= 0.10 && < 0.11 , persistent >= 0.8 && < 0.9+ , transformers ghc-options: -Wall