nonpop / elm-purl / Purl

A tiny library for building parameterized URLs. It is intended to be used with records to give the parameters names and therefore reducing errors.

userUrl : Url { id : Int, show : Bool }
userUrl =
    root |> hash |> s "users" |> int .id |> boolQuery "show" .show

userUrl |> toString { id = 42, show = True }
    --> "/#/users/42?show=true"

Types


type Url a

A URL parameterized over the type a, which is typically a record containing a field for each variable segment and query parameter.

Builders

root : Url a

The root URL.

root |> toString () --> "/"

s : String -> Url a -> Url a

Append an unparameterized (static) segment.

root |> s "users" |> toString () --> "/users"

maybeS : Maybe String -> Url a -> Url a

Append an unparameterized (static) segment with a Maybe value; it is omitted when the value is Nothing.

root
    |> maybeS (Just "users")
    |> maybeS Nothing
    |> maybeS (Just "1")
    |> toString ()
    --> "/users/1"

hash : Url a -> Url a

Append a hash segment.

root
    |> s "base"
    |> hash
    |> s "page"
    |> toString {}
    --> "/base/#/page"

NOTE: Only the first hash is unencoded:

root |> hash |> hash |> toString {} --> "/#/%23"

customRoot : String -> Url a

A custom root URL.

customRoot "http://example.com:8080/"
    |> toString () --> "http://example.com:8080/"

If the string has no trailing slash, one is added:

customRoot "http://example.com:8080"
    |> toString () --> "http://example.com:8080/"

int : (a -> Basics.Int) -> Url a -> Url a

Append an integer segment.

root
    |> s "users"
    |> int .id
    |> toString { id = 42 }
    --> "/users/42"

string : (a -> String) -> Url a -> Url a

Append a string segment.

root
    |> s "say"
    |> string .word
    |> toString { word = "Hello" }
    --> "/say/Hello"

bool : (a -> Basics.Bool) -> Url a -> Url a

Append a boolean segment.

root
    |> bool .show
    |> toString { show = True }
    --> "/true"

custom : (a -> String) -> Url a -> Url a

Append a custom segment.

root
    |> custom (.ids >> List.map String.fromInt >> String.join ";")
    |> toString { ids = [1, 2, 3] }
    --> "/1%3B2%3B3"

maybeInt : (a -> Maybe Basics.Int) -> Url a -> Url a

Append an integer segment with a Maybe value; it is omitted when the value is Nothing.

url : Url { id : Maybe Int }
url =
    root
        |> s "users"
        |> maybeInt .id
        |> s "images"

toString { id = Just 42 } url --> "/users/42/images"
toString { id = Nothing } url --> "/users/images"

maybeString : (a -> Maybe String) -> Url a -> Url a

Append a string segment with a Maybe value; it is omitted when the value is Nothing.

url : Url { word : Maybe String }
url =
    root
        |> s "say"
        |> maybeString .word
        |> s "world"

toString { word = Just "Hello" } url --> "/say/Hello/world"
toString { word = Nothing } url --> "/say/world"

maybeBool : (a -> Maybe Basics.Bool) -> Url a -> Url a

Append a boolean segment with a Maybe value; it is omitted when the value is Nothing.

url : Url { show : Maybe Bool }
url =
    root
        |> maybeBool .show

toString { show = Just True } url --> "/true"
toString { show = Nothing } url --> "/"

maybeCustom : (a -> Maybe String) -> Url a -> Url a

Append a custom segment with a Maybe value; it is omitted when the value is Nothing.

url : Url { ids : Maybe (List Int) }
url =
    root
        |> maybeCustom (.ids >> Maybe.map (List.map String.fromInt >> String.join ";"))

url |> toString { ids = Just [ 1, 2, 3 ] } --> "/1%3B2%3B3"
url |> toString { ids = Nothing } --> "/"

intQuery : String -> (a -> Basics.Int) -> Url a -> Url a

Append an integer query value.

root
    |> s "users"
    |> intQuery "id" .id
    |> toString { id = 42 }
    --> "/users?id=42"

stringQuery : String -> (a -> String) -> Url a -> Url a

Append a string query value.

root
    |> s "say"
    |> stringQuery "word" .word
    |> toString { word = "Hello" }
    --> "/say?word=Hello"

boolQuery : String -> (a -> Basics.Bool) -> Url a -> Url a

Append a boolean query value.

root
    |> boolQuery "show" .show
    |> toString { show = True }
    --> "/?show=true"

customQuery : String -> (a -> String) -> Url a -> Url a

Append a custom query value.

root
    |> customQuery "ids" (.ids >> List.map String.fromInt >> String.join ";")
    |> toString { ids = [1, 2, 3] }
    --> "/?ids=1%3B2%3B3"

maybeIntQuery : String -> (a -> Maybe Basics.Int) -> Url a -> Url a

Append an integer query value with a Maybe value; it is omitted when the value is Nothing.

url : Url { id : Maybe Int }
url =
    root
        |> s "users"
        |> s "images"
        |> maybeIntQuery "id" .id

toString { id = Just 42 } url --> "/users/images?id=42"
toString { id = Nothing } url --> "/users/images"

maybeStringQuery : String -> (a -> Maybe String) -> Url a -> Url a

Append a string query value with a Maybe value; it is omitted when the value is Nothing.

url : Url { word : Maybe String }
url =
    root
        |> s "say"
        |> maybeStringQuery "word" .word

toString { word = Just "Hello" } url --> "/say?word=Hello"
toString { word = Nothing } url --> "/say"

maybeBoolQuery : String -> (a -> Maybe Basics.Bool) -> Url a -> Url a

Append a boolean query value with a Maybe value; it is omitted when the value is Nothing.

url : Url { show : Maybe Bool }
url =
    root
        |> maybeBoolQuery "show" .show

toString { show = Just True } url --> "/?show=true"
toString { show = Nothing } url --> "/"

maybeCustomQuery : String -> (a -> Maybe String) -> Url a -> Url a

Append a custom query value with a Maybe value; it is omitted when the value is Nothing.

url : Url { ids : Maybe (List Int) }
url =
    root
        |> maybeCustomQuery "ids" (.ids >> Maybe.map (List.map String.fromInt >> String.join ";"))

url |> toString { ids = Just [ 1, 2, 3 ] } --> "/?ids=1%3B2%3B3"
url |> toString { ids = Nothing } --> "/"

Presenting

toString : a -> Url a -> String

Give a string representation of the URL, given a value for the parameter.