kadirahq / flow-router

Carefully Designed Client Side Router for Meteor
MIT License
1.09k stars 192 forks source link

Route names instead of URLs, and alternatives to iron routers linkFor/urlFor. #39

Closed ciwolsey closed 9 years ago

ciwolsey commented 9 years ago

Is there a way to create links like with iron routers linkFor / urlFor ?

Also wouldn't it be better to give each route a name so we create links using the name rather than the URL?

Rather than using a url like:

Router.go('/posts');

Use names:

Router.go('postsList');

Creating the route might look something like this:

FlowRouter.route('postsList', '/posts', {
    action: function() {

    }
});

Using names means that if we decide to use a different URL for that route we don't have to change it throughout the application as well.

arunoda commented 9 years ago

Sorry. This is not Iron Router :)

We don't have named routes. That's a core decision. We won't have it. But, you can generate paths very easily. See: https://github.com/meteorhacks/flow-router#flowrouterpathpathdef-params-queryparams

Then you can create a global helper or helper in your template to get the path.

ciwolsey commented 9 years ago

Makes sense, thanks!

arunoda commented 9 years ago

Thanks. Shall we close the issue?

On Wed, Mar 18, 2015 at 5:59 PM Carl Wolsey notifications@github.com wrote:

Makes sense, thanks!

— Reply to this email directly or view it on GitHub https://github.com/meteorhacks/flow-router/issues/39#issuecomment-82948188 .

MaazAli commented 9 years ago

No named routes? I understand that it's a core decision but what's the reasoning behind it? I love some of the concepts of flow router but named routes just seem so important, kind of a deal breaker for me.

elidoran commented 9 years ago

With a name we can use it repeatedly to reference the route path definition stored in the routes configuration. That way, we only need to change a path definition in one place: route configuration. It's easy to generate paths, it isn't as easy to maintain a path definition rewritten in multiple places.

So, I'm also curious why you want to avoid route names.

elidoran commented 9 years ago

I also missed Iron Router's pathFor/urlFor/linkTo and zimme:iron-router-active isActivePath.

So, I threw together two packages to provide them with FlowRouter. I made a base package which isn't router specific by allowing an implementation to be plugged in. I made a second package, depending on the base package, which uses FlowRouter to generate the paths.

The isActivePath stuff doesn't use FlowRouter (or any router at all) and instead grabs the path from the window.location. And accepts either path or regex.

Packages:

  1. cosmos:path-helpers
  2. cosmos:flow-router-path-helpers

They're both a bit rough at the moment. I'll polish their documentation and complete their unit tests in time. I have run the packages in a Meteor project to test their use and they seem good so far.

devonbarrett commented 9 years ago

:+1: to named routes.

vladshcherbin commented 9 years ago

Hi, @arunoda. With all the respect, we need some features to be in the core. Like this one with named routes. Sure, some packages can add this functionality, but it is not cool to install a new package for every move, besides packages can have bugs or be abandoned.

We need some core features to be out of the box. Please, consider adding some features, that users need, in the core.

elidoran commented 9 years ago

tl;dr ==> I use a new routing strategy so I don't miss route names anymore.

After rethinking how I'd do routes with FlowRouter's getParam ability I changed my entire strategy. I now have only two routes for my entire app. One redirects / to a default page (which requires a login, whole app does). The other manages all other routing. I'm using a dashboard style so all paths are hierarchical and there's a sidebar menu with groups of menu items.

I have 5 considerations for routing:

  1. the layout to use
  2. the dashboard context, each one has its own sidebar content. you reach a context by clicking its link in the header. then the sidebar and main content change. for routing, I call this one 'sidebar'
  3. the menu group the user is in. there are multiple links in each group.
  4. the specific menu item in the menu group
  5. a specific ID when viewing a single object [optional param]

So, the main route is:

FlowRouter.route '/:layout/:sidebar/:menu/:item/:id?',
  middlewares: [requireLogin]
  action: (params) ->
    FlowLayout.render params.layout,
      sidebar: params.sidebar
      main:    params.menu + params.item

So, for example, to use the default app layout, to view the admin sidebar, focusing on the user menu group, to view a specific user 12345, I'd have the path:

/app/admin/User/View/12345

I use a combination of menu and item for the name of the template to render in 'main'. So, the name of the template for the above path is UserView. That's also why those words start with a capital letter. Makes the name more readable. It's not so important for the <template name='UserView'> but is helpful for Template.UserView.onCreated and the multiple times I apply things to the Template. Even then, I could use lowercase and have userview.

For links in the user menu group to other user menu items I don't need to change the whole path. I can instead set the item param which will change what's rendered in the 'main' content area. I actually haven't used the linkTo helpers I made recently. I have just typed paths right into the anchor's href. I'll pay more attention to this eventually.

To mark menu items as 'active' I made a new helper to check the menu and item values like this:

<li class="{{at 'User' 'View'}}">   <= defaults to 'active' when true, false otherwise
<span class="{{at 'User' 'View' 'current'}}">   <= can tell it what to return

Also, can use it in an #if block, to include sr-only content for example:

{{#if at 'User' 'View'}}<span class="sr-only">(current)</span>{{/if}}

You probably noticed by now I can't be putting subscriptions in the routes. You're right. I'm using the new Template.subscribe instead. This prevents fast-render support (unfortunately). Can still use subs-manager too.

I like how simple my routing has become like this. I can add templates via packages for entire dashboard contexts (new sidebar menus and their corresponding views) and I only need to link to the context via a link in the header bar.

I also like having the subscriptions right in the templates which use them.

So, would I still like to have route names? Hmm. I still think it's helpful in places.

  1. Test the active link using the route name
  2. Generate links for a route name without rewriting the pathDef
  3. specify which routes middleware should be applied to

With my single route I can't have different names, so, I can't do any of those. But, I can still get those things done:

  1. the at helper I mentioned above
  2. write the path out. they are never routes with an ID so I always know what they are off the top of my head. eventually I'll make a helper for this.
  3. I used a regular expression to test the path. I can control middleware use with that just fine. It's probably faster than testing with an array of route names anyway.

Conclusion: I haven't been missing route names since I began this new strategy.

(this turned into a giant post, I hope you don't mind... I added a tl;dr line at the top)

vladshcherbin commented 9 years ago

@elidoran the problem is that you are reinventing a wheel and trying to use it.

There is an awesome way to handle routing - named routes. We need that, because it is easy to use, convenient and lots of people know how and use it everywhere.

We don't need that new strategies just because there is no support for a feature, that is not supported without a reason.

elidoran commented 9 years ago

@VladShcherbin I understand what you're saying. We're all used to using named routes and they can be used well. We have experience with it, exercised that way of thinking a lot already, and have code for named routes.

FlowRouter reinvents routing. It provides an API for direct access and manipulation of path components. Should we expect each new tool to do things the same way as the others? New tool, new way of thinking and doing. To do named routes, use Iron Router.

I stopped thinking how FlowRouter should be like Iron Router, and other routers, and thought about how to use it effectively, as designed and implemented, and realized I could do it better.

I only need a router to integrate the browser's location into my app so I can use it to change which templates are rendered (with FlowLayout). I can do the rest with the reactivity Meteor provides me. The more I do this the more I like it.

It would help if we documented ways to do common things using FlowRouter's API. Perhaps doing so would also help in clarifying its API. I'm willing to write PR's containing desired examples.

vladshcherbin commented 9 years ago

@elidoran WHY does it reinvent the routing ?

named routes is an awesome way to define your routes. WHY would you need to reinvent the routing?

ember has named routes, laravel has named routes, iron router and many other routers have named routes - they all work and feel awesome. WHY should we do some tricky stuff with this router?

I agree, if this router would provide a more convenient way - sure, we can try. But we already have an AWESOME and CONVENIENT way of routing. WHY wouldn't we use it ?

I like Iron Router, but there are many things in it, bugs, issues, that I don't like. Besides, there are many issues and pr in its repository and nothing is changed for a long time, there is even a question - if the project is dead or not...

Now, we have a nice router, we can change IR to, why can't we make it awesome for all of us?

MaazAli commented 9 years ago

I see named routes as a core feature of any router, something that is constant and is a given. Any major router will come with named routes. That's not where you should be innovating, there isn't really anything to innovate there. You'd be moving a step backward if you remove that functionality.

Also, @elidoran your technique works well for what you're doing, but for a lot of other people it wouldn't make much sense. Everyone has a different way of structuring their routes.

Sivli-Embir commented 9 years ago

I have to agree with the arguments for named routes. @arunoda can you expand on the reason behind not adding named routes to the core package? You usually have a good reason for your decisions and I feel that context would help here.

arunoda commented 9 years ago

Guys, let's carry over the discussion here. https://github.com/meteorhacks/flow-router/pull/58