yesod-examples 0.6.1 → 0.7.0
raw patch · 14 files changed
+157/−241 lines, 14 filesdep +yesod-formdep +yesod-staticdep −persistentdep −timedep ~yesod
Dependencies added: yesod-form, yesod-static
Dependencies removed: persistent, time
Dependency ranges changed: yesod
Files
- src/MkToForm2.hs +0/−15
- src/ajax.lhs +21/−20
- src/blog.lhs +15/−14
- src/chat.hs +26/−24
- src/file-echo.lhs +5/−5
- src/form.lhs +9/−9
- src/generalized-hamlet.lhs +11/−11
- src/i18n.lhs +8/−7
- src/mkToForm.hs +0/−69
- src/pretty-yaml.lhs +23/−23
- src/session.lhs +2/−2
- src/widgets.lhs +14/−15
- synopsis/hamlet.lhs +19/−18
- yesod-examples.cabal +4/−9
− src/MkToForm2.hs
@@ -1,15 +0,0 @@-{-# LANGUAGE TypeFamilies, QuasiQuotes, GeneralizedNewtypeDeriving #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-module MkToForm2 where--import Yesod-import Data.Time (Day)--mkPersist [$persist|-Entry- title String- day Day Desc toFormField=YesodJquery.jqueryDayField'- content Html toFormField=YesodNic.nicHtmlField- deriving-|]
src/ajax.lhs view
@@ -2,7 +2,7 @@ <p>We're going to use jQuery for the Javascript, though anything would work just fine. Also, the AJAX responses will be served as JSON. Let's get started.</p> -> {-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell #-}+> {-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses #-} > import Yesod > import Yesod.Helpers.Static > import Data.Monoid (mempty)@@ -50,21 +50,22 @@ > Ajax pages _ <- getYesod > content <- widgetToPageContent widget > hamletToRepHtml [$hamlet|-> !!!-> %html-> %head-> %title $pageTitle.content$-> %link!rel=stylesheet!href=@StaticR.style_css@-> %script!src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"-> %script!src=@StaticR.script_js@-> ^pageHead.content^-> %body-> %ul#navbar-> $forall pages page-> %li-> %a!href=@PageR.pageSlug.page@ $pageName.page$-> #content-> ^pageBody.content^+> \<!DOCTYPE html>+> +> <html>+> <head>+> <title>#{pageTitle content}+> <link rel="stylesheet" href="@{StaticR style_css}">+> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js">+> <script src="@{StaticR script_js}">+> \^{pageHead content}+> <body>+> <ul id="navbar">+> $forall page <- pages+> <li>+> <a href="@{PageR (pageSlug page)}">#{pageName page}+> <div id="content">+> \^{pageBody content} > |] <p>The Hamlet template refers to style_css and style_js; these were generated by the call to staticFiles above. There's nothing Yesod-specific about the <a href="/static/yesod/ajax/style.css">style.css</a> and <a href="/static/yesod/ajax/script.js">script.js</a> files, so I won't describe them here.</p>@@ -90,8 +91,8 @@ > ) (json page) > where > html page = [$hamlet|-> %h1 $pageName.page$-> %article $pageContent.page$+> <h1>#{pageName page}+> <article>#{pageContent page} > |] > json page = jsonMap > [ ("name", jsonScalar $ pageName page)@@ -107,5 +108,5 @@ > main :: IO () > main = do > pages <- loadPages-> let static = fileLookupDir "static/yesod/ajax" typeByExt-> basicHandler 3000 $ Ajax pages static+> let s = static "static/yesod/ajax"+> warpDebug 3000 $ Ajax pages s
src/blog.lhs view
@@ -2,7 +2,7 @@ <p>This file is literate Haskell, so we'll start off with our language pragmas and import statements. Basically every Yesod application will start off like this:</p> -> {-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell #-}+> {-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses #-} > import Yesod Next, we'll define the blog entry information. Usually, we would want to store the data in a database and allow users to modify them, but we'll simplify for the moment.@@ -70,18 +70,19 @@ > entryTemplate :: TemplateArgs -> Hamlet (Route Blog) > entryTemplate args = [$hamlet| > !!!-> %html-> %head-> %title $templateTitle.args$-> %body-> %h1 Yesod Sample Blog-> %h2 $templateTitle.args$-> %ul#nav-> $forall templateNavbar.args nav-> %li-> %a!href=@navUrl.nav@ $navTitle.nav$-> #content-> $templateContent.args$+> +> <html>+> <head>+> <title>#{templateTitle args}+> <body>+> <h1>Yesod Sample Blog+> <h2>#{templateTitle args}+> <ul id="nav">+> $forall nav <- templateNavbar args+> <li>+> <a href="@{navUrl nav}">#{navTitle nav}+> <div id="content">+> \#{templateContent args} > |] Hopefully, that is fairly easy to follow; if not, please review the Hamlet documentation. Just remember that dollar signs mean Html variables, and at signs mean URLs.@@ -113,4 +114,4 @@ > main :: IO () > main = do > entries <- loadEntries-> basicHandler 3000 $ Blog entries+> warpDebug 3000 $ Blog entries
src/chat.hs view
@@ -1,10 +1,10 @@ {-# LANGUAGE TemplateHaskell, QuasiQuotes, TypeFamilies #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE MultiParamTypeClasses #-} module Main where import Yesod-import Yesod.Handler import Yesod.Helpers.Static import Control.Concurrent.STM@@ -38,18 +38,20 @@ approot _ = "" defaultLayout widget = do content <- widgetToPageContent widget- hamletToRepHtml [$hamlet|- !!!- %html- %head- %title $pageTitle.content$- %script!src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"- %script!src=@StaticR.chat_js@- ^pageHead.content^- %body- ^pageBody.content^- |]+ hamletToRepHtml [$hamlet|\+ \<!DOCTYPE html> + <html>+ <head>+ <title>#{pageTitle content}+ <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js">+ <script src="@{StaticR chat_js}">+ \^{pageHead content}+ <body>+ \^{pageBody content}+ \+|]+ getHomeR :: Handler Chat RepHtml getHomeR = do Chat clients next _ <- getYesod@@ -64,16 +66,17 @@ return c defaultLayout $ do setTitle "Chat Page"- addWidget [$hamlet|-!!!-%h1 Chat Example-%form- %textarea!cols=80!rows=20!name=chat- %p- %input!type=text!size=15!name=name#name- %input!type=text!size=60!name=send#send- %input!type=submit!value=Send-%script var clientNumber = $show client$+ addWidget [$hamlet|\+\<!DOCTYPE html>++<h1>Chat Example+<form>+ <textarea cols="80" rows="20" name="chat">+ <p>+ <input type="text" size="15" name="name" id="name">+ <input type="text" size="60" name="send" id="send">+ <input type="submit" value="Send">+<script>var clientNumber = #{show client} |] getCheckR :: Handler Chat RepJson@@ -117,5 +120,4 @@ main = do clients <- newTVarIO [] next <- newTVarIO 0- let static = fileLookupDir "static" typeByExt- basicHandler 3000 $ Chat clients next static+ warpDebug 3000 $ Chat clients next $ static "static"
src/file-echo.lhs view
@@ -1,7 +1,8 @@-> {-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell #-}+> {-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses #-} > import Yesod > import Data.Monoid (mempty)+> import qualified Data.ByteString.Char8 as S8 > data Echo = Echo @@ -21,9 +22,8 @@ > |] > postHomepage = do-> rr <- getRequest-> (_, files) <- liftIO $ reqRequestBody rr+> (_, files) <- runRequestBody > fi <- maybe notFound return $ lookup "file" files-> return [(fileContentType fi, toContent $ fileContent fi)]+> return [(S8.pack $ fileContentType fi, toContent $ fileContent fi)] -> main = basicHandler 3000 Echo+> main = warpDebug 3000 Echo
src/form.lhs view
@@ -1,7 +1,7 @@ <p>Forms can be a tedious part of web development since they require synchronization of code in many different areas: the HTML form declaration, parsing of the form and reconstructing a datatype from the raw values. The Yesod form library simplifies things greatly. We'll start off with a basic application.</p> -> {-# LANGUAGE TypeFamilies, QuasiQuotes, OverloadedStrings #-}+> {-# LANGUAGE TypeFamilies, QuasiQuotes, OverloadedStrings, MultiParamTypeClasses #-} > import Yesod > import Control.Applicative > data FormExample = FormExample@@ -36,13 +36,13 @@ <p>extractBody returns the HTML of a widget and "passes" all of the other declarations (the CSS, Javascript, etc) up to the parent widget. The rest of this is just standard Hamlet code and our main function.</p> > addHamlet [$hamlet|-> %p Last result: $show.res$-> %form!enctype=$enctype$-> %table-> ^form^-> %tr-> %td!colspan=2-> %input!type=submit+> <p>Last result: #{show res}+> <form enctype="#{enctype}">+> <table>+> \^{form}+> <tr>+> <td colspan="2">+> <input type="submit"> > |] > -> main = basicHandler 3000 FormExample+> main = warpDebug 3000 FormExample
src/generalized-hamlet.lhs view
@@ -11,7 +11,7 @@ This example uses all three. You are of course free in your own code to make your own instances. -> {-# LANGUAGE QuasiQuotes, TypeFamilies #-}+> {-# LANGUAGE QuasiQuotes, TypeFamilies, MultiParamTypeClasses #-} > import Yesod > data NewHamlet = NewHamlet > mkYesod "NewHamlet" [$parseRoutes|/ RootR GET|]@@ -19,13 +19,13 @@ > type Widget = GWidget NewHamlet NewHamlet > > myHtml :: Html-> myHtml = [$hamlet|%p Just don't use any URLs in here!|]+> myHtml = [$hamlet|<p>Just don't use any URLs in here!|] > > myInnerWidget :: Widget () > myInnerWidget = do > addHamlet [$hamlet|-> #inner Inner widget-> $myHtml$+> <div #inner>Inner widget+> #{myHtml} > |] > addCassius [$cassius| >#inner@@ -33,20 +33,20 @@ > > myPlainTemplate :: Hamlet NewHamletRoute > myPlainTemplate = [$hamlet|-> %p-> %a!href=@RootR@ Link to home+> <p+> <a href=@{RootR}>Link to home > |] > > myWidget :: Widget () > myWidget = [$hamlet|-> %h1 Embed another widget-> ^myInnerWidget^-> %h1 Embed a Hamlet-> ^addHamlet.myPlainTemplate^+> <h1>Embed another widget+> \^{myInnerWidget}+> <h1>Embed a Hamlet+> \^{addHamlet myPlainTemplate} > |] > > getRootR :: GHandler NewHamlet NewHamlet RepHtml > getRootR = defaultLayout myWidget > > main :: IO ()-> main = basicHandler 3000 NewHamlet+> main = warpDebug 3000 NewHamlet
src/i18n.lhs view
@@ -1,6 +1,7 @@ > {-# LANGUAGE QuasiQuotes #-} > {-# LANGUAGE TemplateHaskell #-} > {-# LANGUAGE TypeFamilies #-}+> {-# LANGUAGE MultiParamTypeClasses #-} > import Yesod > import Data.Monoid (mempty)@@ -28,12 +29,12 @@ > defaultLayout $ do > setTitle $ string "I18N Homepage" > addHamlet [$hamlet|-> %h1 $hello$-> %p In other languages:-> %ul-> $forall choices choice-> %li-> %a!href=@SetLangR.fst.choice@ $snd.choice$+> <h1>#{hello}+> <p>In other languages:+> <ul>+> $forall choice <- choices+> <li>+> <a href="@{SetLangR (fst choice)}">#{snd choice} > |] > chooseHello :: [String] -> String@@ -48,4 +49,4 @@ > redirect RedirectTemporary HomepageR > main :: IO ()-> main = basicHandler 3000 I18N+> main = warpDebug 3000 I18N
− src/mkToForm.hs
@@ -1,69 +0,0 @@-{-# LANGUAGE TypeFamilies, QuasiQuotes, GeneralizedNewtypeDeriving #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-import Yesod-import Yesod.Helpers.Crud-import Yesod.Form.Jquery-import Yesod.Form.Nic-import Database.Persist.Sqlite-import Database.Persist.TH-import Data.Time (Day)-import MkToForm2--jqueryDayField' :: YesodJquery m => FormFieldSettings -> FormletField s m Day-jqueryDayField' = jqueryDayField def-mkToForm (undefined :: Entry)--instance Item Entry where- itemTitle = entryTitle--data Blog = Blog { pool :: ConnectionPool }--type EntryCrud = Crud Blog Entry--mkYesod "Blog" [$parseRoutes|-/ RootR GET-/entry/#EntryId EntryR GET-/admin AdminR EntryCrud defaultCrud-|]--instance Yesod Blog where- approot _ = "http://localhost:3000"--instance YesodPersist Blog where- type YesodDB Blog = SqlPersist- runDB db = fmap pool getYesod >>= runSqlPool db--instance YesodJquery Blog-instance YesodNic Blog--getRootR = do- entries <- runDB $ selectList [] [EntryDayDesc] 0 0- defaultLayout $ do- setTitle $ string "Yesod Blog Tutorial Homepage"- addHamlet [$hamlet|-%h1 Archive-%ul- $forall entries entry- %li- %a!href=@EntryR.fst.entry@ $entryTitle.snd.entry$-%p- %a!href=@AdminR.CrudListR@ Admin-|]--getEntryR entryid = do- entry <- runDB $ get404 entryid- defaultLayout $ do- setTitle $ string $ entryTitle entry- addHamlet [$hamlet|-%h1 $entryTitle.entry$-%h2 $show.entryDay.entry$-$entryContent.entry$-|]--withBlog f = withSqlitePool "blog.db3" 8 $ \pool -> do- flip runSqlPool pool $ runMigration $ do- migrate (undefined :: Entry)- f $ Blog pool--main = withBlog $ basicHandler 3000
src/pretty-yaml.lhs view
@@ -1,6 +1,6 @@ <p>This example uses the <a href="http://hackage.haskell.org/package/data-object-yaml">data-object-yaml package</a> to display YAML files as cleaned-up HTML. If you've read through the other tutorials, this one should be easy to follow.</p> -> {-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell #-}+> {-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses #-} > import Yesod > import Data.Object@@ -20,17 +20,18 @@ > template :: Maybe (Hamlet url) -> Hamlet url > template myaml = [$hamlet| > !!!-> %html-> %head-> %meta!charset=utf-8-> %title Pretty YAML-> %body-> %form!method=post!action=.!enctype=multipart/form-data-> File name:-> %input!type=file!name=yaml-> %input!type=submit-> $maybe myaml yaml-> %div ^yaml^+> +> <html>+> <head>+> <meta charset="utf-8">+> <title>Pretty YAML+> <body>+> <form method="post" action="" enctype="multipart/form-data" .>+> \File name:+> <input type="file" name="yaml">+> <input type="submit">+> $maybe yaml <- myaml+> <div>^{yaml} > |] > getHomepage :: Handler RepHtml@@ -38,8 +39,7 @@ > postHomepage :: Handler RepHtml > postHomepage = do-> rr <- getRequest-> (_, files) <- liftIO $ reqRequestBody rr+> (_, files) <- runRequestBody > fi <- case lookup "yaml" files of > Nothing -> invalidArgs ["yaml: Missing input"] > Just x -> return x@@ -47,18 +47,18 @@ > hamletToRepHtml $ template $ Just $ objToHamlet so > objToHamlet :: StringObject -> Hamlet url-> objToHamlet (Scalar s) = [$hamlet|$s$|]+> objToHamlet (Scalar s) = [$hamlet|#{s}|] > objToHamlet (Sequence list) = [$hamlet|-> %ul-> $forall list o-> %li ^objToHamlet.o^+> <ul+> $forall o <- list+> <li>^{objToHamlet o} > |] > objToHamlet (Mapping pairs) = [$hamlet|-> %dl-> $forall pairs pair-> %dt $fst.pair$-> %dd ^objToHamlet.snd.pair^+> <dl+> $forall pair <- pairs+> <dt>#{fst pair}+> <dd>^{objToHamlet $ snd pair} > |] > main :: IO ()-> main = basicHandler 3000 PY+> main = warpDebug 3000 PY
src/session.lhs view
@@ -1,4 +1,4 @@-> {-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell #-}+> {-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses #-} > import Yesod > import Control.Applicative ((<$>), (<*>)) > @@ -28,4 +28,4 @@ > instance Yesod Session where > approot _ = "" > clientSessionDuration _ = 1-> main = basicHandler 3000 Session+> main = warpDebug 3000 Session
src/widgets.lhs view
@@ -1,6 +1,5 @@-> {-# LANGUAGE TypeFamilies, QuasiQuotes, OverloadedStrings #-}+> {-# LANGUAGE TypeFamilies, QuasiQuotes, OverloadedStrings, MultiParamTypeClasses #-} > import Yesod-> import Yesod.Widget > import Yesod.Helpers.Static > import Yesod.Form.Jquery > import Yesod.Form.Nic@@ -18,11 +17,11 @@ > instance YesodJquery HW > instance YesodNic HW > wrapper h = [$hamlet|-> #wrapper ^h^-> %footer Brought to you by Yesod Widgets™+> <#wrapper>^{h}+> <footer>Brought to you by Yesod Widgets™ > |] > getRootR = defaultLayout $ wrapper $ do-> i <- newIdent+> i <- lift newIdent > setTitle $ string "Hello Widgets" > addCassius [$cassius| > #$i$@@ -65,19 +64,19 @@ > width: 300px > height: 150px|] > addWidget [$hamlet|-> %form!method=post!enctype=$enctype$-> %table-> ^form^-> %tr-> %td!colspan=2-> $nonce$-> %input!type=submit-> $maybe mhtml html-> $html$+> <form method="post" enctype="#{enctype}">+> <table>+> \^{form}+> <tr>+> <td colspan="2">+> \#{nonce}+> <input type="submit">+> $maybe html <- mhtml+> \#{html} > |] > setTitle $ string "Form" > -> main = basicHandler 3000 $ HW $ fileLookupDir "static" typeByExt+> main = warpDebug 3000 $ HW $ static "static" > > getAutoCompleteR :: Handler RepJson > getAutoCompleteR = do
synopsis/hamlet.lhs view
@@ -18,30 +18,31 @@ renderUrls (PersonPage name) _ = '/' : name footer :: Hamlet url-footer = [$hamlet|-#footer Thank you, come again+footer = [$hamlet|\+<div id="footer">Thank you, come again |] template :: Person -> Hamlet PersonUrls template person = [$hamlet| !!!-%html- %head- %title Hamlet Demo- %body- %h1 Information on $string.name.person$- %p $string.name.person$ is $string.age.person$ years old.- %h2- $if isMarried.person- Married++<html>+ <head>+ <title>Hamlet Demo+ <body>+ <h1>Information on #{string (name person)}+ <p>#{string (name person)} is #{string (age person)} years old.+ <h2>+ $if isMarried person+ \Married $else- Not married- %ul- $forall children.person child- %li $string.child$- %p- %a!href=@page.person@ See the page.- ^footer^+ \Not married+ <ul>+ $forall child <- children person+ <li>#{string child}+ <p>+ <a href="@{page person}">See the page.+ \^{footer} |] main :: IO ()
yesod-examples.cabal view
@@ -1,5 +1,5 @@ Name: yesod-examples-Version: 0.6.1+Version: 0.7.0 Synopsis: Example programs using the Yesod Web Framework. Description: These are the same examples and tutorials found on the documentation site. Homepage: http://docs.yesodweb.com/@@ -18,10 +18,11 @@ Executable blog Main-is: src/blog.lhs Build-depends: base >= 4 && < 5,- yesod >= 0.6 && < 0.7+ yesod >= 0.7 && < 0.8 Executable ajax Main-is: src/ajax.lhs+ Build-depends: yesod-static Executable file-echo Main-is: src/file-echo.lhs@@ -40,19 +41,13 @@ Executable widgets Main-is: src/widgets.lhs+ Build-depends: yesod-form Executable generalized-hamlet Main-is: src/generalized-hamlet.lhs Executable form Main-is: src/form.lhs--Executable mkToForm- Main-is: mkToForm.hs- Build-depends: time,- persistent >= 0.3 && < 0.4- hs-source-dirs: src- other-modules: MkToForm2 Executable persistent-synopsis Main-is: synopsis/persistent.lhs