{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE Rank2Types #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE CPP #-} module Yesod.Helpers.Crud ( Item (..) , Crud (..) , CrudRoute (..) , defaultCrud ) where import Yesod.Core import Text.Hamlet import Yesod.Form import Language.Haskell.TH.Syntax import Yesod.Persist import Data.Text (Text) -- | An entity which can be displayed by the Crud subsite. class Item a where -- | The title of an entity, to be displayed in the list of all entities. itemTitle :: a -> Text -- | Defines all of the CRUD operations (Create, Read, Update, Delete) -- necessary to implement this subsite. When using the "Yesod.Form" module and -- 'ToForm' typeclass, you can probably just use 'defaultCrud'. data Crud master item = Crud { crudSelect :: GHandler (Crud master item) master [(Key item, item)] , crudReplace :: Key item -> item -> GHandler (Crud master item) master () , crudInsert :: item -> GHandler (Crud master item) master (Key item) , crudGet :: Key item -> GHandler (Crud master item) master (Maybe item) , crudDelete :: Key item -> GHandler (Crud master item) master () } mkYesodSub "Crud master item" [ ClassP ''Item [VarT $ mkName "item"] , ClassP ''SinglePiece [ConT ''Key `AppT` VarT (mkName "item")] , ClassP ''ToForm [VarT $ mkName "item", VarT $ mkName "master"] ] #if __GLASGOW_HASKELL__ >= 700 [parseRoutes| #else [$parseRoutes| #endif / CrudListR GET /add CrudAddR GET POST /edit/#Text CrudEditR GET POST /delete/#Text CrudDeleteR GET POST |] getCrudListR :: (Yesod master, Item item, SinglePiece (Key item)) => GHandler (Crud master item) master RepHtml getCrudListR = do items <- getYesodSub >>= crudSelect toMaster <- getRouteToMaster defaultLayout $ do setTitle "Items" addWidget #if __GLASGOW_HASKELL__ >= 700 [hamlet| #else [$hamlet| #endif

Items