Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/lydell/elm-app-url
URLs for applications
https://github.com/lydell/elm-app-url
elm
Last synced: 27 days ago
JSON representation
URLs for applications
- Host: GitHub
- URL: https://github.com/lydell/elm-app-url
- Owner: lydell
- License: mit
- Created: 2022-10-16T14:34:57.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-02-24T19:23:54.000Z (10 months ago)
- Last Synced: 2024-10-25T16:50:00.755Z (about 2 months ago)
- Topics: elm
- Language: Elm
- Homepage: https://package.elm-lang.org/packages/lydell/elm-app-url/latest/
- Size: 306 KB
- Stars: 26
- Watchers: 3
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# elm-app-url
`AppUrl` is an attempt at making URL handling simpler than [elm/url]!
It’s based around this [AppUrl] type:
```elm
type alias AppUrl =
{ path : List String
, queryParameters : QueryParameters
, fragment : Maybe String
}type alias QueryParameters =
Dict String (List String)
```Which works really nicely with pattern matching!
```elm
import AppUrl exposing (AppUrl)
import Dictparse : AppUrl -> Maybe Page
parse url =
case url.path of
[] ->
Just Home[ "product", productId ] ->
String.toInt productId |> Maybe.map (Product << ProductId)[ "products" ] ->
Just
(ListProducts
{ color = Dict.get "color" url.queryParameters |> Maybe.andThen List.head
, size = Dict.get "size" url.queryParameters |> Maybe.andThen List.head
}
)_ ->
Nothingtype Page
= Home
| Product ProductId
| ListProducts Filterstype ProductId
= ProductId Inttype alias Filters =
{ color : Maybe String
, size : Maybe String
}
```Creating URL strings is pretty smooth too:
```elm
import Maybe.ExtratoAppUrl : Page -> AppUrl
toAppUrl page =
case page of
Home ->
AppUrl.fromPath []Product (ProductId productId) ->
AppUrl.fromPath [ "product", String.fromInt productId ]ListProducts { color, size } ->
{ path = [ "products" ]
, queryParameters =
Dict.fromList
[ ( "color", Maybe.Extra.toList color )
, ( "size", Maybe.Extra.toList size )
]
, fragment = Nothing
}toString : Page -> String
toString =
toAppUrl >> AppUrl.toString
```👉 **[Full examples]**
## Design principles
- Parse: Avoid the complex types [Url.Parser] has, and use simple list pattern matching instead. Decode away all percentage escapes so you never need to think about them.
- Stringify: No separate API like [Url.Builder]. Escape the minimum needed with percentage escapes.
- Specification: Follow the [WHATWG URL Standard].
- Keep it simple: URLs shouldn’t be that complicated. List pattern matching, `Dict` and `Maybe` is the bread and butter of `AppUrl`, rather than parsers, tricky type annotations and the `>` and `>` operators.## Tip
It’s completely fine to have something like this:
```elm
parse : AppUrl -> Maybe Page
parse url =
case url.path of
[ "blog" ] -> x
[ "blog", postId ] -> x
[ "blog", postId, "edit" ] -> x
[ "blog", postId, "comment", commentId ] -> x
[ "blog", postId, "comment", commentId, "edit" ] -> x
_ -> Nothing
```It might feel wrong to repeat the URL segment `blog` so many times, for example. My advice is: Don’t try to be clever here for the sake of following the “Don’t Repeat Yourself (DRY)” principle! The above is very simple and easy to read, and gives a nice overview of what all your URLs look like. It’s easy to change too, since all the repetitions of `blog` are in the same place.
Do however avoid duplication in each branch by calling helper functions. But the pattern matching is better left “duplicated”.
[appurl]: https://package.elm-lang.org/packages/lydell/elm-app-url/1.0.4/AppUrl/#AppUrl
[elm/url]: https://package.elm-lang.org/packages/elm/url/latest
[full examples]: https://github.com/lydell/elm-app-url/blob/main/docs/examples.md
[url.builder]: https://package.elm-lang.org/packages/elm/url/latest/Url-Builder
[url.parser]: https://package.elm-lang.org/packages/elm/url/latest/Url-Parser
[whatwg url standard]: https://url.spec.whatwg.org/#urlencoded-parsing