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

can-href link helper #1103

Closed
justinbmeyer opened this Issue Jun 19, 2014 · 17 comments

Comments

Projects
None yet
5 participants
@justinbmeyer
Contributor

justinbmeyer commented Jun 19, 2014

VOTE HERE

We should add a link stache/mustache helper or component or custom attribute.

Helper

<li>{{link recipe.name page='recipe' id=recipe.id}}<li>

Pros - I like the syntax
Cons - Can't easily pass the "style" argument to can.route.link.

Custom Attribute

<li><a can-href='{page="recipe" id=recipe.id}'>{{recipe.name}}</a></li>

Pros - can customize the style, happens directly on a link.
Cons - UGLY

Custom element

<can-link page="recipe" id="{recipe.id}">{{recipe.name}}</a></li>

Pros - pretty, fits in with how components get hooked up
Cons - What about attributes that should be ignored? Do we need a syntax of specifying that? We'd have to add "style". Maybe data-X prevents cross binding on that property?

Qs - would we put an <a> inside or would we implement click / keypress ourselves?

A - we would have to put the <a> inside if we want right click and open in new window ... indexing ... etc.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Jun 19, 2014

Contributor

Another option ... can-href simply adds the behavior of the custom element.

Custom Attribute that hooks up other attributes

<li><a can-href page="recipe" id='{recipe.id}'>{{recipe.name}}</a></li>

Pros - still a link, fits in with how components get hooked up.
Cons - we'd want to pull out some of can.Component's guts to help set this up.

Contributor

justinbmeyer commented Jun 19, 2014

Another option ... can-href simply adds the behavior of the custom element.

Custom Attribute that hooks up other attributes

<li><a can-href page="recipe" id='{recipe.id}'>{{recipe.name}}</a></li>

Pros - still a link, fits in with how components get hooked up.
Cons - we'd want to pull out some of can.Component's guts to help set this up.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Jul 8, 2014

Contributor
<a can-href route-page="recipe" route-id='{recipe.id}'>{{recipe.name}}</a>
Contributor

justinbmeyer commented Jul 8, 2014

<a can-href route-page="recipe" route-id='{recipe.id}'>{{recipe.name}}</a>

@justinbmeyer justinbmeyer added this to the 2.2.0 milestone Aug 26, 2014

@justinbmeyer justinbmeyer changed the title from Link helper or custom attribute. to can-href link helper Aug 26, 2014

@sporto

This comment has been minimized.

Show comment
Hide comment
@sporto

sporto Aug 27, 2014

Contributor

IMO helpers like {{link recipe.name page='recipe' id=recipe.id}} are not great, they make things more difficult, what if I want to add a title, aria-role, class, data or whatever, helpers need to account for a way of doing all these.

I see custom attribute or custom elements as a better way, as you are free to modify the html tag as you see fit.

Could you pass a json like object to the custom attr version? e.g.

<a can-href="{page: recipes, id: recipe.id}">{{recipe.name}}</a>

However I'm confused about the possible syntax. Some common patterns I use:

/#recipes
/#recipes/1
/#recipes/1/edit
/#recipies/search?foo=bar
/#users/1/recipes

The first two are clear, how would you express the others?

Contributor

sporto commented Aug 27, 2014

IMO helpers like {{link recipe.name page='recipe' id=recipe.id}} are not great, they make things more difficult, what if I want to add a title, aria-role, class, data or whatever, helpers need to account for a way of doing all these.

I see custom attribute or custom elements as a better way, as you are free to modify the html tag as you see fit.

Could you pass a json like object to the custom attr version? e.g.

<a can-href="{page: recipes, id: recipe.id}">{{recipe.name}}</a>

However I'm confused about the possible syntax. Some common patterns I use:

/#recipes
/#recipes/1
/#recipes/1/edit
/#recipies/search?foo=bar
/#users/1/recipes

The first two are clear, how would you express the others?

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Aug 27, 2014

Contributor

We are going the <a can-href route-page="recipe" route-id='{recipe.id}'>{{recipe.name}}</a> ... um ... route! Although the object notation would be nice too.

How would would you express the last two?

This depends on what pretty routes you setup. Put probably like:

<a can-href route-id="{id}" route-action='edit'>{{recipe.name}}</a>
<a can-href route-id="{id}" route-action='search' route-foo="bar">{{recipe.name}}</a>
Contributor

justinbmeyer commented Aug 27, 2014

We are going the <a can-href route-page="recipe" route-id='{recipe.id}'>{{recipe.name}}</a> ... um ... route! Although the object notation would be nice too.

How would would you express the last two?

This depends on what pretty routes you setup. Put probably like:

<a can-href route-id="{id}" route-action='edit'>{{recipe.name}}</a>
<a can-href route-id="{id}" route-action='search' route-foo="bar">{{recipe.name}}</a>
@sporto

This comment has been minimized.

Show comment
Hide comment
@sporto

sporto Aug 27, 2014

Contributor

I think is worth looking at how the API is resolved in React-Routes https://github.com/rackt/react-router/blob/master/docs/api/components/Link.md

Something like:

<can-link route-to="recipe" route-params='{id: recipe.id}' route-query='{foo: bar}'>{recipe.name}</can-link>

I find this very easy to understand. But they rely heavily on named routes for this which Can doesn't have atm. Anyway, something to consider.

Contributor

sporto commented Aug 27, 2014

I think is worth looking at how the API is resolved in React-Routes https://github.com/rackt/react-router/blob/master/docs/api/components/Link.md

Something like:

<can-link route-to="recipe" route-params='{id: recipe.id}' route-query='{foo: bar}'>{recipe.name}</can-link>

I find this very easy to understand. But they rely heavily on named routes for this which Can doesn't have atm. Anyway, something to consider.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Aug 27, 2014

Contributor

What's about:

<a can-href="{id: id, action: 'search', foo: 'bar'}">{{recipe.name}}</a>

?

Does React have 2 way routing? CanJS treats all data the same. There is no "params" vs "query" data. The determinism of CanJS's routing, although confusing at first, is very powerful. I don't think named routes would be a benefit.

Contributor

justinbmeyer commented Aug 27, 2014

What's about:

<a can-href="{id: id, action: 'search', foo: 'bar'}">{{recipe.name}}</a>

?

Does React have 2 way routing? CanJS treats all data the same. There is no "params" vs "query" data. The determinism of CanJS's routing, although confusing at first, is very powerful. I don't think named routes would be a benefit.

@sporto

This comment has been minimized.

Show comment
Hide comment
@sporto

sporto Aug 27, 2014

Contributor

No, I don't think that React-routes does two way route binding.

This is a convoluted example but worth using, how would you link to:

/#user/1/comments/search?foo=bar

In React-Routes you would do:

<Link to="user_comments_search" params={{userId: user.id}} query={{foo: bar}}>Search</Link>
Contributor

sporto commented Aug 27, 2014

No, I don't think that React-routes does two way route binding.

This is a convoluted example but worth using, how would you link to:

/#user/1/comments/search?foo=bar

In React-Routes you would do:

<Link to="user_comments_search" params={{userId: user.id}} query={{foo: bar}}>Search</Link>
@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Aug 27, 2014

Contributor

@sporto it's all about how you setup your pretty routes. But any other "how to do canjs routing" questions, please ask on the forums.

There's a lot of ways to structure your pretty routes depending on the situation. If you're site was pretty uniform in the url structure, you could do:

can.route("user/:userId/:part/:action",{type: "user"});

and

<a can-href="{type: 'user', userId: user.id, part: 'comments', action: 'search', foo: 'bar'}">Search</a>

If we made it possible to set "merge" and you were currently on the user/1 page, you would only have to write something like:

<a can-href="{part: 'comments', action: 'search', foo: 'bar'}" can-href-merge>Search</a>

I suppose some naming might help make things nicer. Being able to mixin: {type: "user", part: 'comments', action: 'search'} so you didn't have to write it so many times.

can.route("user/:userId/comments/search",
           {type: "user",part: "comments", action: "search"},
           "user_comments_search")
<a can-href="{route: 'user_comments_search'}" can-href-merge>Search</a>
Contributor

justinbmeyer commented Aug 27, 2014

@sporto it's all about how you setup your pretty routes. But any other "how to do canjs routing" questions, please ask on the forums.

There's a lot of ways to structure your pretty routes depending on the situation. If you're site was pretty uniform in the url structure, you could do:

can.route("user/:userId/:part/:action",{type: "user"});

and

<a can-href="{type: 'user', userId: user.id, part: 'comments', action: 'search', foo: 'bar'}">Search</a>

If we made it possible to set "merge" and you were currently on the user/1 page, you would only have to write something like:

<a can-href="{part: 'comments', action: 'search', foo: 'bar'}" can-href-merge>Search</a>

I suppose some naming might help make things nicer. Being able to mixin: {type: "user", part: 'comments', action: 'search'} so you didn't have to write it so many times.

can.route("user/:userId/comments/search",
           {type: "user",part: "comments", action: "search"},
           "user_comments_search")
<a can-href="{route: 'user_comments_search'}" can-href-merge>Search</a>
@stevenvachon

This comment has been minimized.

Show comment
Hide comment
@stevenvachon

stevenvachon Aug 27, 2014

Contributor

I currently use these helpers: https://github.com/stevenvachon/can-boilerplate/blob/master/root/client/private/components/app/helpers/urls.js

like

<a href="{{app-route-section 'something'}}">something</a>
Contributor

stevenvachon commented Aug 27, 2014

I currently use these helpers: https://github.com/stevenvachon/can-boilerplate/blob/master/root/client/private/components/app/helpers/urls.js

like

<a href="{{app-route-section 'something'}}">something</a>
@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Sep 8, 2014

Contributor

maybe this should be can-route as the attribute name.

Contributor

justinbmeyer commented Sep 8, 2014

maybe this should be can-route as the attribute name.

@matthewp

This comment has been minimized.

Show comment
Hide comment
@matthewp

matthewp Sep 10, 2014

Contributor

I think can-href is the correct attribute name. If we wind up creating a can-route component it would be confusing to have a can-route attribute that is for something completely different.

Contributor

matthewp commented Sep 10, 2014

I think can-href is the correct attribute name. If we wind up creating a can-route component it would be confusing to have a can-route attribute that is for something completely different.

@daffl daffl modified the milestones: 2.3.0, 2.2.0 Jan 10, 2015

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Apr 13, 2015

Contributor

For consistency, I think we are going to go with this:

<li><a can-href='{page="recipe" id=recipe.id}'>{{recipe.name}}</a></li>

This will be easiest to implement and work similar to can-EVENT and passing options to helpers..

Contributor

justinbmeyer commented Apr 13, 2015

For consistency, I think we are going to go with this:

<li><a can-href='{page="recipe" id=recipe.id}'>{{recipe.name}}</a></li>

This will be easiest to implement and work similar to can-EVENT and passing options to helpers..

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Apr 13, 2015

Contributor

can-href

Sets an element's href attribute so that it's url will set the specified attribute values on [can.route].

@siganture can-href='{[attrName=attrValue...]}'

@param {String} attrName
@param {can.stache.key} attrValue

Use

With no pretty routing rules, the following:

<li><a can-href='{page="recipe" id=5}'>{{recipe.name}}</a></li>

produces:

<li><a href='#!page=5&id=5'>{{recipe.name}}</a></li>

If pretty route is defined like:

can.route(":page/:id")

The previous use of can-href will instead produce:

<li><a href='#!page/5'>{{recipe.name}}</a></li>

You can use values from stache's scope like:

<li><a can-href='{page="recipe" id=recipeId}'>{{recipe.name}}</a></li>

If recipeId was 6:

<li><a href='#!page/6'>{{recipe.name}}</a></li>

If recipeId is observable and changes to 7:

<li><a href='#!page/7'>{{recipe.name}}</a></li>
Contributor

justinbmeyer commented Apr 13, 2015

can-href

Sets an element's href attribute so that it's url will set the specified attribute values on [can.route].

@siganture can-href='{[attrName=attrValue...]}'

@param {String} attrName
@param {can.stache.key} attrValue

Use

With no pretty routing rules, the following:

<li><a can-href='{page="recipe" id=5}'>{{recipe.name}}</a></li>

produces:

<li><a href='#!page=5&id=5'>{{recipe.name}}</a></li>

If pretty route is defined like:

can.route(":page/:id")

The previous use of can-href will instead produce:

<li><a href='#!page/5'>{{recipe.name}}</a></li>

You can use values from stache's scope like:

<li><a can-href='{page="recipe" id=recipeId}'>{{recipe.name}}</a></li>

If recipeId was 6:

<li><a href='#!page/6'>{{recipe.name}}</a></li>

If recipeId is observable and changes to 7:

<li><a href='#!page/7'>{{recipe.name}}</a></li>
@stevenvachon

This comment has been minimized.

Show comment
Hide comment
@stevenvachon

stevenvachon Apr 13, 2015

Contributor

Wouldn't <a can-href="{page:'recipe', id:recipeId}"> be more javascript-like ?

Contributor

stevenvachon commented Apr 13, 2015

Wouldn't <a can-href="{page:'recipe', id:recipeId}"> be more javascript-like ?

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Apr 14, 2015

Contributor

@stevenvachon it wouldn't be more mustache/stache like. Plus we already have a parser for foo=bar.

Contributor

justinbmeyer commented Apr 14, 2015

@stevenvachon it wouldn't be more mustache/stache like. Plus we already have a parser for foo=bar.

@stevenvachon

This comment has been minimized.

Show comment
Hide comment
Contributor

stevenvachon commented Apr 14, 2015

@daffl

This comment has been minimized.

Show comment
Hide comment
@daffl

daffl Oct 22, 2015

Contributor

This has been added in 2.3 (but is already deprecated in favour of the routeCurrent and routeUrl helpers).

Contributor

daffl commented Oct 22, 2015

This has been added in 2.3 (but is already deprecated in favour of the routeCurrent and routeUrl helpers).

@daffl daffl closed this Oct 22, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment