Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make a Router #4

Open
bradleypeabody opened this issue Mar 29, 2019 · 4 comments
Open

Make a Router #4

bradleypeabody opened this issue Mar 29, 2019 · 4 comments

Comments

@bradleypeabody
Copy link
Contributor

bradleypeabody commented Mar 29, 2019

There's a lot of functionality that is only feasible with a "router", although we need to define what that means.

Examples of things that need to work:

  • Get a list of "all of the pages" and write static output, sitemap.xml, etc.
  • Check if a path is valid (both client-side and server-side), implement 404.
  • Display component based on path... with nesting... (/section/feature/part or whatever)... and somehow query params fit in too.
  • Do the reverse and take component state and generate a URL from it.
  • Browse to pages dynamically and deal with browser history.
  • Anchor to text on page (bear in mind the anchor may not exist on page load so the browser's default behavior won't work in this case, we might have to scroll manually).
  • URLs should be able to use history.pushState or also put everything in fragment, depending on config. This also affects static site generation - one case to think with is where the main 50 pages of a blog are all statically generated, but then one page is dynamic (assuming the wasm stuff loads successfully) and has its state controlled by fragment.
  • Needs to work both client and server side (or at least templates need to compile, event handlers won't get called when outputting static html).
  • Need to render specific content in a region based on path pattern (more applicable to server-side, but overall useful).
  • Custom behaviors should be possible. If someone comes along and says "I want my URLs to work exactly according to this custom logic", it should be possible and not mean other code that is calling the router to browse to pages, etc. will break.

Needs some careful thought on the design and maybe a prototype or two. Likely a separate package.

@erinpentecost
Copy link
Contributor

Are you basically looking for a port of Vue's router?

@bradleypeabody
Copy link
Contributor Author

bradleypeabody commented Mar 30, 2019

Thanks for the links. I'm not really sure yet what the right approach is. The Vue router is pretty cool but there are things that I "feel I should be able to do" with it that are not simple.

For example, if I'm making some big screen with various controls in it, it would be really handy to be able to just "bind" the query parameters (or perhaps something in the path too?) directly to the data in my component. The rough pseudocode would be like:

type MyCompData struct {
    ShowLeftPanel bool   `urlparam:"showleft"`
    DisplayID     string `urlparam:"id"`
    SomeThingElse int    `urlparam:"-"` // explicitly not included in URL params
}
// and then somewhere, not sure where, I can do:
router.Bind(data) // data is *MyCompData - tell router to synchronize URL in both directions

And this would result in /path/to/page?showleft=true&id=whatever - and if the user changes the URL it updates the data in the component and if the component changes data it updates the URL.

I'm not aware of a way to do this with the Vue router. But it's functionality that I've often wanted. I'd like to figure out a design that solves it (without precluding other cases that Vue's router does solve well). This is something I will give more thought to over the coming days and then prototype. Suggestions welcome.

Some more random thoughts, just so I don't forget: "Browser" seems like an interface to me, with a "BrowseTo" method or some such. Likewise, the difference between encoding data into the query string or into the fragment could be two different router implementations. Figuring out how to effectively use the Go type system will be important here, otherwise the result will be one giant struct with a bunch of random options on it and will be hard to reason about and maintain. The functionality show in the code snippet above could be described by a "Binder" interface, possibly.

@bradleypeabody
Copy link
Contributor Author

@bradleypeabody bradleypeabody moved this from To do to In progress in Old Vugu Dev Sep 23, 2019
@bradleypeabody bradleypeabody moved this from In progress to Done in Old Vugu Dev Apr 26, 2020
@bradleypeabody
Copy link
Contributor Author

Vugu Router works reasonably well now: https://www.vugu.org/doc/routing

@bradleypeabody bradleypeabody removed this from Done in Old Vugu Dev Apr 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants