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

can-href link helper #1103

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

can-href link helper #1103

justinbmeyer opened this issue Jun 19, 2014 · 17 comments
Milestone

Comments

@justinbmeyer
Copy link
Contributor

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
Copy link
Contributor Author

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
Copy link
Contributor Author

<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 Link helper or custom attribute. can-href link helper Aug 26, 2014
@sporto
Copy link
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
Copy link
Contributor Author

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
Copy link
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
Copy link
Contributor Author

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
Copy 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
Copy link
Contributor Author

@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
Copy link
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>

@justinbmeyer
Copy link
Contributor Author

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

@matthewp
Copy link
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.

@daffl daffl modified the milestones: 2.3.0, 2.2.0 Jan 10, 2015
@justinbmeyer
Copy link
Contributor Author

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
Copy link
Contributor Author

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
Copy link
Contributor

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

@justinbmeyer
Copy link
Contributor Author

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

@stevenvachon
Copy link
Contributor

Ah, yes: http://handlebarsjs.com/expressions.html#helpers
Thanks

@daffl
Copy link
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 as completed Oct 22, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants