module Snap.Snaplet.ReCaptcha.Example
(
main
, initSample
, sampleTemplate
, initBlog
) where
import qualified Blaze.ByteString.Builder as Blaze
import Heist
import Heist.Compiled
import Snap
import Snap.Snaplet.Heist.Compiled
import Snap.Snaplet.ReCaptcha
import Control.Applicative
import Control.Lens
import Control.Monad.Trans
import qualified Data.ByteString.Char8 as BS
import Data.Monoid
import Data.Text (Text)
data Sample = Sample
{ _recaptcha :: !(Snaplet ReCaptcha)
, _heist :: !(Snaplet (Heist Sample))
, _blog :: !(Snaplet Blog)
}
data Blog = Blog
{ _currentPost :: !(Maybe BS.ByteString)
}
makeLenses ''Sample
makeLenses ''Blog
instance HasReCaptcha Sample where
captchaLens = subSnaplet recaptcha
instance HasHeist Sample where
heistLens = subSnaplet heist
initBlog :: forall b. (HasReCaptcha b, HasHeist b) => Snaplet (Heist b)
-> SnapletInit b Blog
initBlog heist = makeSnaplet "blog" "simple blog" Nothing $ do
me <- getLens
addRoutes
[("/posts/:id", method GET displayPost <|> method POST commentOnPost)]
addConfig heist $ mempty &~ do
scCompiledSplices .=
("blog-post" ## pureSplice Blaze.fromByteString . lift $ do
post' <- withTop' me (use currentPost)
case post' of
Just post -> return post
Nothing -> fail "Couldn't find that.")
return (Blog Nothing)
where
displayPost :: Handler b Blog ()
displayPost = do
Just postId <- getParam "id"
currentPost .= Just ("there is no post #" <> postId <> ". only me.")
render "recaptcha-example" <|> fail "Couldn't load recaptcha-example.tpl"
commentOnPost :: Handler b Blog ()
commentOnPost = do
Just postId <- getParam "id"
checkCaptcha <|> fail "Bad captcha response."
Just name <- getPostParam "name"
Just email <- getPostParam "email"
Just content <- getPostParam "content"
writeBS $ BS.concat [postId, " < (", name,", ", email, ", ", content, ")"]
sampleTemplate :: Text
sampleTemplate =
"<html>\
\ <head>\
\ <recaptcha-script />\
\ </head>\
\ <body>\
\ <form method='POST'>\
\ <input type='text' name='name' placeholder='Name'>\
\ <input type='text' name='email' placeholder='Email'>\
\ <br>\
\ <textarea class='field' name='content' rows='20' placeholder='Content'></textarea>\
\ <br>\
\ <recaptcha-div />\
\ <input type='submit' value='Comment'>\
\ </form>\
\ </body>\
\</html>"
initSample :: SnapletInit Sample Sample
initSample = makeSnaplet "sample" "" Nothing $ do
h <- nestSnaplet "heist" heist (heistInit "templates")
c <- nestSnaplet "submit" recaptcha (initReCaptcha (Just h))
t <- nestSnaplet "blog" blog (initBlog h)
return (Sample c h t)
main :: IO ()
main = serveSnaplet defaultConfig initSample