sporto / hop

[Deprecated] Navigation and routing helpers for single page applications in Elm
MIT License
293 stars 21 forks source link

Nested routes, trailing slash #38

Open FAQinghere opened 8 years ago

FAQinghere commented 8 years ago

When I set up a test app as per the nested routes example, the root nested route (users) only works if I add the trailing slash (users/). Non-nested routes match both with and without the trailing slash. Is there any way to get the root nested routes to also match without the trailing slash?

I got it working by changing the main matcher format for the nested routes to simply "nestedMatchers," moving the oneOf and even the root nested path up to into the nested route definitions), and ensuring that the root nested path last.

Just out of curiosity, why is it that the matches on the non-base nested paths don't match when the base nested path (ex. admin, as opposed to admin/users, etc) comes first? In such cases the base nested path matches, but no other nested paths match, and it doesn't just seem to be a case of first one wins, because the base nested path is not matched when trying to reach the non-base nested paths.

i.e. both match okay with: format AdminSubRoute (s "admin" </> s "users") format AdminUsersRoute (s "admin")

but only the first matches with: format AdminBaseRoute (s "admin") format AdminUsersRoute (s "admin" </> s "users")

Also, is there a better way of doing this? I like having the base nested path up in the main matchers definition (like in the nested routes example here), because then the base nested path doesn't get repeated inside every non-base nested path definition. But again, this only worked for me if the base nested path includes the trailing slash.

sporto commented 8 years ago

Hi, will try to go over your questions

re having to add users/ This is a limitation of using UrlParser.format UsersRoute (s "") as the root nested route.

UrlParsers requires to have a / to match. All matchers in UrlParser require a leading /.

example:

import UrlParser exposing ((</>), format, s, parse)

type UserRoute = UsersRoute
type MainRoute = UsersRoutes UserRoute

usersMatcher = format UsersRoute (s "")

matcher = format UsersRoutes (s "users" </> usersMatcher)

parse identity matcher "users/" == Ok (UsersRoutes UsersRoute)

To avoid this issue when running in the browser I add the trailing slash in here https://github.com/sporto/hop/blob/master/src/Hop.elm#L161

This seems to work fine when running in the browser with nested routes.

Have you run into this issue when running in the browser or just in test/repl? It would be great to improve this situation.

sporto commented 8 years ago

Re second question added this https://github.com/sporto/hop/blob/master/docs/building-routes.md#order-matters

FAQinghere commented 8 years ago

I am running into the issue when running in the browser. /admin/users would not load, but /admin/users/ would. At the root level, both /users and /users/ worked fine. I worked around it by pulling the "admin" portion up into the sub-matchers (so at the root of the subroutes there is "admin", not "", and then the "admin" segment gets repeated in each sub-matcher.

Regarding the ordering - thank you for adding additional docs. Less tired now, and looking at both your added docus and the relevant libs, I can see why the system is behaving the way that it is. To summarize then, the first match does "win", but it matches strictly and therefore it fails (after matching) because it sees that there are extra parts hanging out there that were not used.

It's easy to work around (a little re-arranging is all that it takes).

I'm pretty new to Elm, but does the way it works not seem a little semantically inconsistent? A "match" initially means "good enough to trigger this case, thus ignoring the rest of the matchers," but then it fails because it wasn't a perfect and complete match. I would think that it either is or is not a match. If it is a match, it should show the chosen Route. If it isn't a match, it should continue on to check the other matchers.

sporto commented 8 years ago

re matchers order, I agree with you. You could bring this issue in https://github.com/evancz/url-parser

sporto commented 8 years ago

re, having to add / in the browser. I will like to improve this. Can you: