don't bother with TH for static page routes

This commit is contained in:
Greg Weber 2012-02-09 17:38:25 -08:00 committed by gregwebs
parent 60a6df9765
commit 9c867721c5
6 changed files with 25 additions and 93 deletions

View File

@ -17,7 +17,6 @@ module Yesod.Dispatch
, mkYesodSubData , mkYesodSubData
, mkYesodDispatch , mkYesodDispatch
, mkYesodSubDispatch , mkYesodSubDispatch
, mkYesodStaticPages
-- ** Path pieces -- ** Path pieces
, PathPiece (..) , PathPiece (..)
, PathMultiPiece (..) , PathMultiPiece (..)
@ -54,29 +53,9 @@ import Network.HTTP.Types (status301)
import Yesod.Routes.TH import Yesod.Routes.TH
import Yesod.Content (chooseRep) import Yesod.Content (chooseRep)
import Yesod.Routes.Parse import Yesod.Routes.Parse
import Data.List (partition)
type Texts = [Text] type Texts = [Text]
mkYesodStaticPages :: String -> [StaticPageRoute] -> Q [Dec]
mkYesodStaticPages name routes =
let (staticGets, staticResources) = partition isGet routes
gets = ListE (map (LitE . StringL . toString) staticGets)
getsD = ValD (VarP (mkName "staticPageRoutePaths")) (NormalB gets) []
in do yesod <- mkYesod name (map toResource staticResources)
return $ [getsD] ++ yesod
where
isGet (StaticGet _) = True
isGet (StaticResource _) = False
toResource (StaticResource r) = r
toResource (StaticGet _) = error "expected resource"
toString (StaticGet str) = dropSlashes str
toString (StaticResource _) = error "did not expect resource"
dropSlashes str | last str == '/' = dropSlashes $ init str
| head str == '/' = dropSlashes $ tail str
| otherwise = str
-- | Generates URL datatype and site function for the given 'Resource's. This -- | Generates URL datatype and site function for the given 'Resource's. This
-- is used for creating sites, /not/ subsites. See 'mkYesodSub' for the latter. -- is used for creating sites, /not/ subsites. See 'mkYesodSub' for the latter.
-- Use 'parseRoutes' to create the 'Resource's. -- Use 'parseRoutes' to create the 'Resource's.

View File

@ -12,7 +12,6 @@ import YesodCoreTest.Cache
import qualified YesodCoreTest.WaiSubsite as WaiSubsite import qualified YesodCoreTest.WaiSubsite as WaiSubsite
import qualified YesodCoreTest.Redirect as Redirect import qualified YesodCoreTest.Redirect as Redirect
import qualified YesodCoreTest.JsLoader as JsLoader import qualified YesodCoreTest.JsLoader as JsLoader
import qualified YesodCoreTest.StaticPages as StaticPages
import Test.Hspec import Test.Hspec
@ -30,5 +29,4 @@ specs =
, WaiSubsite.specs , WaiSubsite.specs
, Redirect.specs , Redirect.specs
, JsLoader.specs , JsLoader.specs
, StaticPages.specs
] ]

View File

@ -1,33 +0,0 @@
{-# OPTIONS_GHC -fno-warn-unused-binds #-}
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
module YesodCoreTest.StaticPages (specs) where
import Test.Hspec
import Test.Hspec.HUnit ()
import Test.HUnit
import Yesod.Core
import Yesod.Routes.Parse (staticPageRoutes)
data StaticPages = StaticPages
mkYesodStaticPages "StaticPages" [staticPageRoutes|
/pages/ PageR
/pages/
about
data
faq
|]
instance Yesod StaticPages where approot _ = ""
handlePageR :: Handler RepHtml
handlePageR = defaultLayout [whamlet|Hello World!|]
specs :: [Spec]
specs = describe "staticPageRoutePaths" [
it "lists static page routes" $
["pages","pages/about","pages/data","pages/faq"] @=? staticPageRoutePaths
]

View File

@ -127,7 +127,6 @@ test-suite tests
, random , random
,HUnit ,HUnit
,QuickCheck >= 2 && < 3 ,QuickCheck >= 2 && < 3
, yesod-routes >= 0.0 && < 0.1
ghc-options: -Wall ghc-options: -Wall
source-repository head source-repository head

View File

@ -7,15 +7,12 @@ module Yesod.Routes.Parse
, parseRoutesNoCheck , parseRoutesNoCheck
, parseRoutesFileNoCheck , parseRoutesFileNoCheck
, parseType , parseType
, staticPageRoutes , parseRoutePaths
, staticPageRoutesFile
, StaticPageRoute (..)
) where ) where
import Language.Haskell.TH.Syntax import Language.Haskell.TH.Syntax
import Data.Maybe import Data.Maybe
import Data.Char (isUpper, isSpace) import Data.Char (isUpper, isSpace)
import Data.List (intercalate)
import Language.Haskell.TH.Quote import Language.Haskell.TH.Quote
import qualified System.IO as SIO import qualified System.IO as SIO
import Yesod.Routes.TH import Yesod.Routes.TH
@ -55,37 +52,26 @@ parseRoutesNoCheck :: QuasiQuoter
parseRoutesNoCheck = QuasiQuoter parseRoutesNoCheck = QuasiQuoter
{ quoteExp = lift . resourcesFromString } { quoteExp = lift . resourcesFromString }
-- | QuasiQuoter for 'staticPageRoutesFromString' -- | Convert a multi-line string to a set of route paths.
staticPageRoutes :: QuasiQuoter -- like normal route parsing, but there are just route paths, no route constructors or HTTP methods
staticPageRoutes = QuasiQuoter -- This can be used as a DSL for generating route paths that
{ quoteExp = lift . staticPageRoutesFromString } -- * closely matches your current routes file
-- * allows indentation to imply prefixes
-- | parse a file with 'staticPageRoutesFromString' --
staticPageRoutesFile :: FilePath -> Q Exp
staticPageRoutesFile fp = do
s <- qRunIO $ readUtf8File fp
quoteExp staticPageRoutes s
data StaticPageRoute = StaticGet String | StaticResource (Resource String)
instance Lift StaticPageRoute where
lift (StaticGet str) = [|StaticGet $(lift str)|]
lift (StaticResource r) = [|StaticResource $(lift r)|]
-- | Convert a multi-line string to a set of routes.
-- like normal route parsing, but there are just route paths, no route constructors
-- This is a partial function which calls 'error' on invalid input. -- This is a partial function which calls 'error' on invalid input.
staticPageRoutesFromString :: String -> [StaticPageRoute] parseRoutePaths :: String -> [String]
staticPageRoutesFromString = parseRoutesFromString staticPageRoute parseRoutePaths = parseRoutesFromString staticPageRoute
where where
staticPageRoute r [] = Just (StaticGet r) staticPageRoute :: String -> [String] -> Maybe String
staticPageRoute r rest = fmap StaticResource $ resourceFromLine r rest staticPageRoute r [] = Just r
staticPageRoute r rest = error $ "line starting with: " ++ r ++ "\ndid not expect: " ++ show rest
-- | Convert a multi-line string to a set of resources. See documentation for -- | Convert a multi-line string to a set of resources. See documentation for
-- the format of this string. This is a partial function which calls 'error' on -- the format of this string. This is a partial function which calls 'error' on
-- invalid input. -- invalid input.
resourcesFromString :: String -> [Resource String] resourcesFromString :: String -> [Resource String]
resourcesFromString = resourcesFromString =
parseRoutesFromString justResourceFromLine parseRoutesFromString resourceFromLine
resourceFromLine :: String -> [String] -> Maybe (Resource String) resourceFromLine :: String -> [String] -> Maybe (Resource String)
resourceFromLine fullRoute (constr:rest) = resourceFromLine fullRoute (constr:rest) =
@ -95,12 +81,6 @@ resourceFromLine fullRoute (constr:rest) =
resourceFromLine _ [] = Nothing -- an indenter: there should be indented routes afterwards resourceFromLine _ [] = Nothing -- an indenter: there should be indented routes afterwards
justResourceFromLine :: String -> [String] -> Maybe (Resource String)
justResourceFromLine x xs =
case resourceFromLine x xs of
Nothing -> error $ "Invalid resource line: " ++ (intercalate " " (x:xs))
r -> r
-- | used by 'resourcesFromString' and 'staticPageRoutesFromString' -- | used by 'resourcesFromString' and 'staticPageRoutesFromString'
parseRoutesFromString :: (String -- ^ route pattern parseRoutesFromString :: (String -- ^ route pattern
-> [String] -- ^ extra -> [String] -- ^ extra

View File

@ -10,16 +10,17 @@
{-# LANGUAGE CPP #-} {-# LANGUAGE CPP #-}
import Test.Hspec.Monadic import Test.Hspec.Monadic
import Test.Hspec.HUnit () import Test.Hspec.HUnit ()
import Test.HUnit ((@?=)) import Test.HUnit ((@?=), (@=?))
import Data.Text (Text, pack, unpack, singleton) import Data.Text (Text, pack, unpack, singleton)
import Yesod.Routes.Dispatch hiding (Static, Dynamic) import Yesod.Routes.Dispatch hiding (Static, Dynamic)
import Yesod.Routes.Class hiding (Route) import Yesod.Routes.Class hiding (Route)
import qualified Yesod.Routes.Class as YRC import qualified Yesod.Routes.Class as YRC
import qualified Yesod.Routes.Dispatch as D import qualified Yesod.Routes.Dispatch as D
import Yesod.Routes.Parse (parseRoutesNoCheck) import Yesod.Routes.Parse (parseRoutesNoCheck, parseRoutePaths)
import Yesod.Routes.Overlap (findOverlapNames) import Yesod.Routes.Overlap (findOverlapNames)
import Yesod.Routes.TH hiding (Dispatch) import Yesod.Routes.TH hiding (Dispatch)
import Language.Haskell.TH.Syntax import Language.Haskell.TH.Syntax
import Data.List (intercalate)
class ToText a where class ToText a where
toText :: a -> Text toText :: a -> Text
@ -224,7 +225,15 @@ thDispatchAlias master sub toMaster app404 handler405 method0 pieces0 =
-} -}
main :: IO () main :: IO ()
main = hspecX $ do main = hspecX $ do
describe "parseRoutePaths" $
it "lists static page routes" $
["/pages/","/pages/about","/pages/data","/pages/faq"] @=? parseRoutePaths (intercalate "\n" [
"/pages/"
," about"
," data"
," faq"
])
describe "justRoot" $ do describe "justRoot" $ do
it "dispatches correctly" $ test justRoot [] @?= Just 1 it "dispatches correctly" $ test justRoot [] @?= Just 1
it "fails correctly" $ test justRoot ["foo"] @?= Nothing it "fails correctly" $ test justRoot ["foo"] @?= Nothing