Skip to content
This repository has been archived by the owner on Nov 9, 2021. It is now read-only.

Adding BreadcrumbList schema.org spec #119

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions addon/components/bread-crumb.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import Ember from 'ember';
import layout from '../templates/components/bread-crumb';

const {
Component,
computed
get,
set,
computed,
Component
} = Ember;
const {
oneWay,
Expand All @@ -14,8 +16,28 @@ export default Component.extend({
layout,
tagName: 'li',
classNameBindings: ['crumbClass'],
attributeBindings: [],

crumbClass: oneWay('breadCrumbs.crumbClass'),
linkClass: oneWay('breadCrumbs.linkClass'),
hasBlock: bool('template').readOnly()
hasSchema: oneWay('breadCrumbs.hasSchema'),
hasBlock: bool('template').readOnly(),
itemscope: true,
itemtype: 'http://schema.org/ListItem',
itemprop: 'itemListElement',

position: computed('index', function() {
return Number(this.get('index') + 1);
}).readOnly(),

init() {
this._super(...arguments);
const hasSchema = get(this, 'breadCrumbs.hasSchema');
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to do this in two places we could move it a mixin.


if (hasSchema) {
const newAttributeBindings = ['itemprop', 'itemscope', 'itemtype'];

set(this, 'attributeBindings', this.attributeBindings.concat(newAttributeBindings));
}
}
});
20 changes: 20 additions & 0 deletions addon/components/bread-crumbs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import layout from '../templates/components/bread-crumbs';

const {
get,
set,
Component,
computed,
copy,
Expand All @@ -13,6 +14,7 @@ const {
typeOf,
setProperties,
getOwner,
LinkComponent,
A: emberArray,
String: { classify }
} = Ember;
Expand All @@ -26,11 +28,29 @@ export default Component.extend({
tagName: 'ol',
linkable: true,
reverse: false,
hasSchema: false,
classNameBindings: ['breadCrumbClass'],
attributeBindings: [],
itemscope: true,
itemtype: 'http://schema.org/BreadcrumbList',
hasBlock: bool('template').readOnly(),
currentUrl: readOnly('applicationRoute.router.url'),
currentRouteName: readOnly('applicationRoute.controller.currentRouteName'),

init() {
this._super(...arguments);

LinkComponent.reopen({
Copy link
Author

@kiwiupover kiwiupover May 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to reopen the LinkComponent to add attributeBindings but need to do this behind the hasSchema flag. However that is too late in the code execution path.

Also to make this backward compatible we need a version flag to switch to LinkView in pre 2.10 apps.

Do you have thoughts about?
We could move the configuration to the ENV and reopen the LinkComponent in the initializer

attributeBindings: ['itemscope', 'itemtype', 'itemprop']
});

if (get(this, 'hasSchema')) {
const newAttributeBindings = ['itemscope', 'itemtype'];

set(this, 'attributeBindings', this.attributeBindings.concat(newAttributeBindings));
}
},

routeHierarchy: computed('currentUrl', 'currentRouteName', 'reverse', {
get() {
const currentRouteName = getWithDefault(this, 'currentRouteName', false);
Expand Down
30 changes: 23 additions & 7 deletions addon/templates/components/bread-crumb.hbs
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
{{#if route.linkable}}
{{#link-to route.path class=linkClass}}
{{#if hasBlock}}
{{yield this route}}
{{else}}
{{route.title}}
{{/if}}
{{#link-to route.path class=linkClass itemscope=true itemtype="http://schema.org/Thing" itemprop="item"}}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI These attrs it the link-to with not be compiled if we don't reopen the LinkComponent

Have you thought about using the href-to addon here?

{{#if hasBlock}}
{{yield this route}}
{{else}}
{{#if hasSchema}}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could make one more component to clean up this level of nest ifs

<span itemprop="name">
{{route.title}}
</span>
{{else}}
{{route.title}}
{{/if}}
{{/if}}
{{/link-to}}
{{#if hasSchema}}
<meta itemprop="position" content={{position}}>
{{/if}}
{{else}}
{{#if hasBlock}}
{{yield this route}}
{{else}}
{{route.title}}
{{#if hasSchema}}
<span itemprop="name">
{{route.title}}
</span>
<meta itemprop="position" content={{position}}>
{{else}}
{{route.title}}
{{/if}}
{{/if}}
{{/if}}
4 changes: 2 additions & 2 deletions addon/templates/components/bread-crumbs.hbs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{{#each routeHierarchy as |route|}}
{{#each routeHierarchy as |route index|}}
{{#if hasBlock}}
{{yield this route}}
{{else}}
{{bread-crumb route=route breadCrumbs=this}}
{{bread-crumb route=route breadCrumbs=this index=index}}
{{/if}}
{{/each}}
20 changes: 20 additions & 0 deletions tests/acceptance/integration-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,3 +297,23 @@ test('uses path from breadCrumb if present', function(assert) {
assert.equal(currentRouteName(), 'foo.index', 'correct current route name');
});
});

test('use schema.org BreadcrumbList Schema if present', function(assert) {
assert.expect(12);
visit('/bar/baz');

andThen(() => {
assert.equal(find('#hasSchema').attr('itemtype'), 'http://schema.org/BreadcrumbList', 'correct itemtype');
assert.equal(find('#hasSchema').attr('itemscope'), '', 'has itemscope');
assert.equal(find('#hasSchema li:first').attr('itemtype'), 'http://schema.org/ListItem', 'li has itemtype');
assert.equal(find('#hasSchema li:first').attr('itemscope'), '', 'li has itemscope');
assert.equal(find('#hasSchema li:first').attr('itemprop'), 'itemListElement', 'li has correct itemprop');
assert.equal(find('#hasSchema li:first a').attr('itemtype'), 'http://schema.org/Thing', 'li a has correct itemtype');
assert.equal(find('#hasSchema li:first a').attr('itemprop'), 'item', 'li a has correct itemprop');
assert.equal(find('#hasSchema li:first a').attr('itemscope'), '', 'li a has correct itemscope');
assert.equal(find('#hasSchema li:first a span').attr('itemprop'), 'name', 'li a span has correct itemprop');
assert.equal(find('#hasSchema li:first > meta').attr('itemprop'), 'position', 'meta tag itemprop should be position');
assert.equal(find('#hasSchema li:first > meta').attr('content'), '1', '1st meta tag correct content');
assert.equal(find('#hasSchema li:last > meta').attr('content'), '2', '2nd meta tag correct content');
});
});
4 changes: 4 additions & 0 deletions tests/dummy/app/templates/application.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
{{bread-crumbs id="foundationNotLinkable" tagName="ul" outputStyle="foundation" linkable=false}}
<hr>

<h2>With BreadcrumbList Schema</h2>
{{bread-crumbs id="hasSchema" hasSchema=true}}
<hr>

<h2>Custom block</h2>
{{#bread-crumbs id="customBlock" as |component route|}}
{{#bread-crumb route=route breadCrumbs=component}}
Expand Down