Skip to content


Subversion checkout URL

You can clone with
Download ZIP


If overriding tagName on linkTo helper, generate an inner A tag #1849

wants to merge 1 commit into from

8 participants


This has come up a fair bit on IRC and a few times on StackOverflow but none of the solutions seem particularly nice.

I've modified linkTo to detect if the tagName has been given and isn't 'a', then instead of generating invalid HTML (eg <li href="/foo" class="active">...</li>) then it will use a layout which contains the a tag (eg <li class="active"><a href="/foo">...</a></li>).

I'm not 100% on whether this is the correct implementation, especially if layout is going to go on the outside of the View in future, but hopefully good for some discussion.


Nice, but I managed to achieve the same thing with very little effort:

{{#linkTo 'accounts' tagName='li' href=false}}
  {{#linkTo 'accounts'}}Accounts{{/linkTo}}

you can use href=false
this will get rid of href

{{#linkTo 'profile' tagName="li" href=false}}


@joelmoss you can do that, but would be nice to have native support which doesn't require doubling up on helpers, eg:

{{#linkTo accounts tagName='li'}}Accounts{{/linkTo}}

@raila that works, but you lose the benefit of the href being used to bookmark the link or open in a new tab etc...


I recall reading that Yehuda has said they will add a helper for that active class.

Here is a solution that can be used in the meantime:

(I also agree with what rlivsey points out, that using href is a good practice for many reasons)


I'm a bit hesitant to create an extra tag since this doesn't have precedent elsewhere in Ember. However, I'll leave this open for more discussion.


joelmoss' solution is great, and very clean, with the caveat that you have to type 'accounts' twice.

In #1822 nragaz proposed this: {{#linkTo index tagName="li"}}Index{{/linkTo}

Weaving in the href=false trick, I think we may have a 'clean-ish' solution as with: {{#linkTo index tagName="li" href=false}} < a {{bindAttr href="view.href"}} >Index< / a >{{/linkTo}

edit: spaces added to mask the inner a-tag from the formatter.


I don't think we should make the #linkTo helper create multiple tags. The solution by @joelmoss is a reasonable workaround for now. We'll consider the issue of the Bootstrap setup more thoroughly in the weeks ahead.

@wycats wycats closed this
@kielpedia kielpedia referenced this pull request in hodgesmr/Empress

boostrap active link set on correct tag #7


Notice that sine ember v1.0.0-rc.3 the href defaults to false if tagName !== 'a'

@MiguelMadero MiguelMadero referenced this pull request from a commit in kielpedia/Empress
@kielpedia kielpedia boostrap active link set on correct tag c2d16e3
@olgabrani olgabrani referenced this pull request from a commit in olgabrani/synnefo
@olgabrani olgabrani ember-ui: Active class to link container 16b5139
@avakhov avakhov referenced this pull request from a commit in snowman-io/snowman-io
@avakhov avakhov Fix #53 703ac77
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
22 packages/ember-routing/lib/helpers/link_to.js
@@ -33,14 +33,13 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
return ret.concat(resolvedPaths(linkView.parameters));
- var LinkView = Ember.View.extend({
+ var LinkViewMixin = Ember.Mixin.create({
tagName: 'a',
namedRoute: null,
currentWhen: null,
title: null,
activeClass: 'active',
replace: false,
- attributeBindings: ['href', 'title'],
classNameBindings: 'active',
active: Ember.computed(function() {
@@ -78,8 +77,18 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
+ var LinkView = Ember.View.extend(LinkViewMixin, {
+ attributeBindings: ['href', 'title']
+ });
LinkView.toString = function() { return "LinkView"; };
+ var LinkContainerView = Ember.View.extend(LinkViewMixin, {
+ layout: Ember.Handlebars.compile('<a {{bindAttr href=view.href title=view.title}}>{{yield}}</a>')
+ });
+ LinkContainerView.toString = function() { return "LinkContainerView"; };
Ember.Handlebars.registerHelper('linkTo', function(name) {
var options = [], -1)[0];
var params = [], 1, -1);
@@ -95,7 +104,14 @@ Ember.onLoad('Ember.Handlebars', function(Handlebars) {
params: params
- return, LinkView, options);
+ var viewClass;
+ if (hash.tagName && hash.tagName !== 'a') {
+ viewClass = LinkContainerView;
+ } else {
+ viewClass = LinkView;
+ }
+ return, viewClass, options);
24 packages/ember/tests/helpers/link_to_test.js
@@ -336,3 +336,27 @@ test("The {{linkTo}} helper accepts string arguments", function() {
equal(Ember.$('#link', '#qunit-fixture').attr('href'), "/filters/unpopular");
+test("The {{linkTo}} helper nests the A tag if a different tagName is given", function() {
+ Ember.TEMPLATES.index = Ember.Handlebars.compile("<h3>Home</h3>{{#linkTo about id='about-link' tagName='p' title='title-attr'}}About{{/linkTo}}{{#linkTo index id='self-link' activeClass='zomg-active' tagName='p'}}Self{{/linkTo}}");
+ {
+ this.route("about");
+ });
+ bootApplication();
+ {
+ router.handleURL("/");
+ });
+ equal(Ember.$('h3:contains(Home)', '#qunit-fixture').length, 1, "The home template was rendered");
+ equal(Ember.$('#self-link.zomg-active', '#qunit-fixture').length, 1, "The self-link was rendered with active class");
+ equal(Ember.$('#about-link:not(.active)', '#qunit-fixture').length, 1, "The other link was rendered without active class");
+ equal(Ember.$('#self-link a', '#qunit-fixture').attr('href'), "/");
+ equal(Ember.$('#about-link a', '#qunit-fixture').attr('href'), "/about");
+ equal(Ember.$('#about-link a', '#qunit-fixture').attr('title'), 'title-attr', "The about-link contains title attribute");
Something went wrong with that request. Please try again.