A simpler alternative to Url.Parser
module from the elm/url
package.
Note that if you want to build both URL parsers and builders at the same time,
you should use the Url.Codec
module instead. The API is very similar!
Parser knows how to parse an URL string into Elm data.
Create it with the combinators:
Use it to parse URLs with the functions parsePath
and parseUrl
.
Leading and trailing slashes don't matter.
All the ways the parsing can fail.
parsePath : List (Parser a) -> String -> Result ParseError a
Parse the URL path string, trying out multiple parsers if necessary.
Will stop at the first success.
Will prefer to report error from the parser that had most success parsing.
allParsers =
[ helloParser, homeParser ]
Url.SimpleParser.parse allParsers "hello/123"
--> Ok (HelloPage 123)
Url.SimpleParser.parse allParsers "/hello/123?comments=1"
--> Ok (HelloPage 123)
Url.SimpleParser.parse allParsers "hello/123whoops"
--> Err (WasNotInt "123whoops")
Url.SimpleParser.parse allParsers ""
--> Ok HomePage
Url.SimpleParser.parse [] ""
--> Err NoParsers
parseUrl : List (Parser parseResult) -> Url -> Result ParseError parseResult
A variant of parsePath
that accepts an
Url
.
succeed : a -> Parser a
A way to start your Parser definition.
unfinishedParser : Parser (String -> Route)
unfinishedParser =
-- needs a string provided via a combinator like `Url.SimpleParser.string`
Url.SimpleParser.succeed UserRoute
Can also work standalone for URLs without path segments:
parser : Parser Route
parser =
Url.SimpleParser.succeed HomeRoute
Url.SimpleParser.parsePath [parser] ""
--> Ok HomeRoute
s : String -> Parser a -> Parser a
A hardcoded path segment.
parser : Parser Route
parser =
Url.SimpleParser.succeed HomeRoute
|> Url.SimpleParser.s "home"
Url.SimpleParser.parsePath [parser] "home"
--> Ok HomeRoute
int : Parser (Basics.Int -> a) -> Parser a
An integer path segment.
type Route
= UserRoute Int
| ...
parser : Parser Route
parser =
Url.SimpleParser.succeed UserRoute
|> Url.SimpleParser.s "user"
|> Url.SimpleParser.int
Url.SimpleParser.parsePath [parser] "user/123"
--> Ok (UserRoute 123)
Url.SimpleParser.parsePath [parser] "user"
--> Err SegmentNotAvailable
string : Parser (String -> a) -> Parser a
A string path segment.
type Route
= PostRoute String
| ...
parser : Parser Route
parser =
Url.SimpleParser.succeed PostRoute
|> Url.SimpleParser.s "post"
|> Url.SimpleParser.string
Url.SimpleParser.parsePath [parser] "post/hello"
--> Ok (PostRoute "hello")
Url.SimpleParser.parsePath [parser] "post"
--> Err SegmentNotAvailable
queryInt : String -> Parser (Maybe Basics.Int -> a) -> Parser a
An integer query parameter.
type Route
= UserRoute (Maybe Int)
| ...
parser : Parser Route
parser =
Url.SimpleParser.succeed UserRoute
|> Url.SimpleParser.s "user"
|> Url.SimpleParser.queryInt "id"
Url.SimpleParser.parsePath [parser] "user?id=123"
--> Ok (UserRoute (Just 123))
Url.SimpleParser.parsePath [parser] "user"
--> Ok (UserRoute Nothing)
Will fail if there are multiple query parameters with the same key:
Url.SimpleParser.parsePath [parser] "user?id=1&id=2"
--> Err (NeededSingleQueryParameterValueGotMultiple { got = ["1","2"], key = "id" })
Will succeed with Nothing if the query parameter contains a non-integer string:
Url.SimpleParser.parsePath [parser] "user?id=martin"
--> Ok (UserRoute Nothing)
queryString : String -> Parser (Maybe String -> a) -> Parser a
A string query parameter.
type Route
= UserRoute (Maybe String)
| ...
parser : Parser Route
parser =
Url.SimpleParser.succeed UserRoute
|> Url.SimpleParser.s "user"
|> Url.SimpleParser.queryString "name"
Url.SimpleParser.parsePath [parser] "user?name=martin"
--> Ok (UserRoute (Just "martin"))
Will fail if there are multiple query parameters with the same key:
Url.SimpleParser.parsePath [parser] "user?name=a&name=b"
--> Err (NeededSingleQueryParameterValueGotMultiple { got = ["a","b"], key = "name" })
queryInts : String -> Parser (List Basics.Int -> a) -> Parser a
A repeated integer query parameter.
type Route
= UserListingRoute (List Int)
| ...
parser : Parser Route
parser =
Url.SimpleParser.succeed UserListingRoute
|> Url.SimpleParser.s "users"
|> Url.SimpleParser.queryInts "id"
Url.SimpleParser.parsePath [parser] "users?id=1"
--> Ok (UserListingRoute [1])
Url.SimpleParser.parsePath [parser] "users?id=1&id=2&id=3"
--> Ok (UserListingRoute [1,2,3])
Url.SimpleParser.parsePath [parser] "users"
--> Ok (UserListingRoute [])
Will fail if given a query parameter with an empty value:
Url.SimpleParser.parsePath [parser] "users?id="
--> Err (NotAllQueryParameterValuesWereInts { got = [ "" ] , key = "id" })
Will fail if any of the query parameters has a non-integer value:
Url.SimpleParser.parsePath [parser] "users?id=1&id=hello"
--> Err (NotAllQueryParameterValuesWereInts { got = [ "1", "hello" ] , key = "id" })
queryStrings : String -> Parser (List String -> a) -> Parser a
A repeated string query parameter.
type Route
= UserListingRoute (List String)
| ...
parser : Parser Route
parser =
Url.SimpleParser.succeed UserListingRoute
|> Url.SimpleParser.s "users"
|> Url.SimpleParser.queryInts "tags"
Url.SimpleParser.parsePath [parser] "users?tags=Foo"
--> Ok (UserListingRoute ["Foo"])
Url.SimpleParser.parsePath [parser] "users?tags=Foo&tags=Bar&tags=999"
--> Ok (UserListingRoute ["Foo", "Bar", "999"])
Url.SimpleParser.parsePath [parser] "users"
--> Ok (UserListingRoute [])
Will succeed with an empty string if given a query parameter with an empty value:
Url.SimpleParser.parsePath [parser] "users?tags="
--> Ok (UserListingRoute [""])
queryFlag : String -> Parser (Basics.Bool -> a) -> Parser a
A query flag (parameter without =
and a value), like eg. /settings?admin
.
type Route
= SettingsRoute { admin : Bool }
| ...
parser : Parser Route
parser =
Url.SimpleParser.succeed (\admin -> SettingsRoute { admin = admin })
|> Url.SimpleParser.s "settings"
|> Url.SimpleParser.queryFlag "admin"
Url.SimpleParser.parsePath [parser] "settings?admin"
--> Ok (SettingsRoute { admin = True })
Url.SimpleParser.parsePath [parser] "settings"
--> Ok (SettingsRoute { admin = False })
allQueryFlags : Parser (List String -> a) -> Parser a
All query flags, like eg. /settings?admin&no-exports
.
type Route
= SettingsRoute (List String)
| ...
parser : Parser Route
parser =
Url.SimpleParser.succeed SettingsRoute
|> Url.SimpleParser.s "settings"
|> Url.SimpleParser.allQueryFlags
Url.SimpleParser.parsePath [parser] "settings?admin"
--> Ok (SettingsRoute ["admin"])
Url.SimpleParser.parsePath [parser] "settings"
--> Ok (SettingsRoute [])
Url.SimpleParser.parsePath [parser] "settings?admin&no-exports"
--> Ok (SettingsRoute ["admin", "no-exports"])
fragment : Parser (Maybe String -> a) -> Parser a
Fragment part of the URL, eg. /settings#HelloThereWorld
.
type Route
= SettingsRoute (Maybe String)
| ...
parser : Parser Route
parser =
Url.SimpleParser.succeed SettingsRoute
|> Url.SimpleParser.s "settings"
|> Url.SimpleParser.fragment
Url.SimpleParser.parsePath [parser] "settings#abc"
--> Ok (SettingsRoute (Just "abc"))
Url.SimpleParser.parsePath [parser] "settings"
--> Ok (SettingsRoute Nothing)
Url.SimpleParser.parsePath [parser] "settings#"
--> Ok (SettingsRoute (Just ""))