Add part9

This commit is contained in:
Richard Feldman
2018-08-12 14:05:15 -04:00
parent fa84d31f62
commit 17f96d1b56
55 changed files with 5948 additions and 0 deletions

107
intro/part9/src/Route.elm Normal file
View File

@@ -0,0 +1,107 @@
module Route exposing (Route(..), fromUrl, href, replaceUrl)
import Article.Slug as Slug exposing (Slug)
import Browser.Navigation as Nav
import Html exposing (Attribute)
import Html.Attributes as Attr
import Profile exposing (Profile)
import Url exposing (Url)
import Url.Parser as Parser exposing ((</>), Parser, oneOf, s, string)
import Username exposing (Username)
-- ROUTING
type Route
= Home
| Root
| Login
| Logout
| Register
| Settings
| Article Slug
| Profile Username
| NewArticle
| EditArticle Slug
parser : Parser (Route -> a) a
parser =
oneOf
[ Parser.map Home Parser.top
, Parser.map Login (s "login")
, Parser.map Logout (s "logout")
, Parser.map Settings (s "settings")
, Parser.map Profile (s "profile" </> Username.urlParser)
, Parser.map Register (s "register")
, Parser.map Article (s "article" </> Slug.urlParser)
, Parser.map NewArticle (s "editor")
, Parser.map EditArticle (s "editor" </> Slug.urlParser)
]
-- PUBLIC HELPERS
href : Route -> Attribute msg
href targetRoute =
Attr.href (routeToString targetRoute)
replaceUrl : Nav.Key -> Route -> Cmd msg
replaceUrl key route =
Nav.replaceUrl key (routeToString route)
fromUrl : Url -> Maybe Route
fromUrl url =
-- The RealWorld spec treats the fragment like a path.
-- This makes it *literally* the path, so we can proceed
-- with parsing as if it had been a normal path all along.
{ url | path = Maybe.withDefault "" url.fragment, fragment = Nothing }
|> Parser.parse parser
-- INTERNAL
routeToString : Route -> String
routeToString page =
let
pieces =
case page of
Home ->
[]
Root ->
[]
Login ->
[ "login" ]
Logout ->
[ "logout" ]
Register ->
[ "register" ]
Settings ->
[ "settings" ]
Article slug ->
[ "article", Slug.toString slug ]
Profile username ->
[ "profile", Username.toString username ]
NewArticle ->
[ "editor" ]
EditArticle slug ->
[ "editor", Slug.toString slug ]
in
"#/" ++ String.join "/" pieces