Skip to content

Commit b238b77

Browse files
fix(authors): authors without posts will use their twitter profile instead of their author page used as their link, fixes GoogleChrome#2904 (GoogleChrome#2965)
* fix(authors): authors without posts will use their twitter profile instead of their author page used as their link, fixes GoogleChrome#2904 * refactor: filter for percy in `authorsWithPosts` collection
1 parent 035f4f8 commit b238b77

File tree

12 files changed

+121
-41
lines changed

12 files changed

+121
-41
lines changed

.eleventy.js

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const YouTube = require(`./${componentsDir}/YouTube`);
5050

5151
const collectionsDir = 'src/site/_collections';
5252
const authors = require(`./${collectionsDir}/authors`);
53+
const authorsWithPosts = require(`./${collectionsDir}/authors-with-posts`);
5354
const paginatedAuthors = require(`./${collectionsDir}/paginated-authors`);
5455
const paginatedBlogPosts = require(`./${collectionsDir}/paginated-blog-posts`);
5556
const paginatedNewsletters = require(`./${collectionsDir}/paginated-newsletters`);
@@ -151,6 +152,7 @@ module.exports = function(config) {
151152
// ----------------------------------------------------------------------------
152153
// COLLECTIONS
153154
// ----------------------------------------------------------------------------
155+
config.addCollection('authorsWithPosts', authorsWithPosts);
154156
config.addCollection('authors', authors);
155157
config.addCollection('blogPosts', blogPostsDescending);
156158
config.addCollection('postsWithLighthouse', postsWithLighthouse);

jsconfig.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"include": [
3+
"src/**/*.js"
4+
]
5+
}

src/@typedefs.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* @typedef {Object} AdditionalData
3+
* @property {string} [title]
4+
* @property {string} [href]
5+
* @property {string} [description]
6+
* @property {string} [tag]
7+
*/
8+
9+
/**
10+
* @typedef {Object} Author
11+
* @property {string} [description]
12+
* @property {string} [title]
13+
* @property {string} [key]
14+
* @property {string} [href]
15+
* @property {string} [url]
16+
* @property {Object} [data]
17+
* @property {string} [data.title]
18+
* @property {string} [data.subhead]
19+
* @property {string} [data.hero]
20+
* @property {string} [data.alt]
21+
* @property {Array<Object>} [elements]
22+
*/
23+
24+
/**
25+
* @typedef {Object} Paginated
26+
* @property {string} [title]
27+
* @property {string} [href]
28+
* @property {string} [description]
29+
* @property {string} [tag]
30+
* @property {Array<Object>} elements
31+
* @property {number} [index]
32+
* @property {number} [pages]
33+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2020 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
const authorsCollection = require('./authors');
17+
18+
/**
19+
* Returns authors filtered by if they have a post.
20+
*
21+
* @param {any} collections Eleventy collection object
22+
* @return {Array<Author>}
23+
*/
24+
module.exports = (collections) => {
25+
const testAuthors = [
26+
'robdodson',
27+
'samthor',
28+
'surma',
29+
'mgechev',
30+
'addyosmani',
31+
'adamargyle',
32+
];
33+
34+
return Object.values(authorsCollection(collections)).filter((author) => {
35+
if (process.env.PERCY && !testAuthors.includes(author.key)) {
36+
return;
37+
}
38+
return author.elements.length > 0;
39+
});
40+
};

src/site/_collections/authors.js

+19-26
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ const setdefault = require('../_utils/setdefault');
2222
/**
2323
* Generate map the posts by author's username/key
2424
*
25-
* @param {Array<any>} posts
26-
* @return {Map<string, Array<any>>} Map of posts by author's username/key
25+
* @param {Array<{ data: { authors: any[] }}>} posts
26+
* @return {Map<string, Array<Object>>} Map of posts by author's username/key
2727
*/
2828
const findAuthorsPosts = (posts) => {
2929
const authorsMap = new Map();
@@ -42,7 +42,7 @@ const findAuthorsPosts = (posts) => {
4242
* Finds image of author, returns path.
4343
*
4444
* @param {string} key
45-
* @return {string} Path for image.
45+
* @return {string | void} Path for image.
4646
*/
4747
const findAuthorsImage = (key) => {
4848
for (const size of ['@3x', '@2x', '']) {
@@ -57,18 +57,9 @@ const findAuthorsImage = (key) => {
5757
* Returns all authors with their posts.
5858
*
5959
* @param {any} collections Eleventy collection object
60-
* @return {Array<{ description: string, title: string, key: string, href: string, url: string, data: { title: string, subhead: string, hero: string, alt: string }, elements: Array<any> }>}
60+
* @return {Object.<string, Author>}
6161
*/
6262
module.exports = (collections) => {
63-
const testAuthors = [
64-
'robdodson',
65-
'samthor',
66-
'surma',
67-
'mgechev',
68-
'addyosmani',
69-
'adamargyle',
70-
];
71-
7263
// Get all posts and sort them
7364
const posts = collections
7465
.getFilteredByGlob('**/*.md')
@@ -77,37 +68,39 @@ module.exports = (collections) => {
7768

7869
const authorsPosts = findAuthorsPosts(posts);
7970

80-
const authors = Object.values(contributors)
71+
/** @constant @type {Object.<string, Author>} @default */
72+
const authors = {};
73+
74+
Object.values(contributors)
8175
.sort((a, b) => a.title.localeCompare(b.title))
82-
.reduce((accumulator, author) => {
83-
if (process.env.PERCY && !testAuthors.includes(author.key)) {
84-
return accumulator;
85-
}
76+
.forEach((author) => {
8677
// This updates the shared contributors object with meta information and is safe to be called multiple times.
8778
author.url = path.join('/en', author.href);
8879
author.data = {
8980
title: author.title,
9081
subhead: author.description,
9182
};
83+
9284
author.elements = authorsPosts.has(author.key)
9385
? authorsPosts.get(author.key)
9486
: [];
87+
88+
if (author.elements.length === 0) {
89+
author.href = `https://twitter.com/${author.twitter}`;
90+
}
91+
9592
const authorsImage = findAuthorsImage(author.key);
9693
if (authorsImage) {
9794
author.data.hero = authorsImage;
9895
author.data.alt = author.title;
9996
}
10097

101-
if (author.elements.length > 0) {
102-
if (process.env.PERCY) {
103-
author.elements = author.elements.slice(-6);
104-
}
105-
106-
accumulator.push(author);
98+
if (process.env.PERCY) {
99+
author.elements = author.elements.slice(-6);
107100
}
108101

109-
return accumulator;
110-
}, []);
102+
authors[author.key] = author;
103+
});
111104

112105
return authors;
113106
};

src/site/_collections/paginated-authors.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
const authorsCollection = require('./authors');
16+
const authorsCollection = require('./authors-with-posts');
1717
const addPagination = require('../_utils/add-pagination');
1818

1919
/**
@@ -25,7 +25,7 @@ const addPagination = require('../_utils/add-pagination');
2525
* embedded loop O^2.
2626
*
2727
* @param {any} collections Eleventy collection object
28-
* @return {Array<{ title: string, href: string, description: string, elements: Array<object>, index: number, pages: number }>} An array where each element is a page with some meta data and n authors for the page.
28+
* @return {Array<Paginated>} An array where each element is a page with some meta data and n authors for the page.
2929
*/
3030
module.exports = (collections) => {
3131
const authors = authorsCollection(collections);

src/site/_collections/paginated-posts-by-author.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
const authorsCollection = require('./authors');
17+
const authorsCollection = require('./authors-with-posts');
1818
const addPagination = require('../_utils/add-pagination');
1919

2020
/**
@@ -27,10 +27,12 @@ const addPagination = require('../_utils/add-pagination');
2727
* embedded loop O^2.
2828
*
2929
* @param {any} collections Eleventy collection object
30-
* @return {Array<{ title: string, href: string, description: string, elements: Array<object>, index: number, pages: number }>} An array where each element is a paged tag with some meta data and n posts for the page.
30+
* @return {Array<Paginated>} An array where each element is a paged tag with some meta data and n posts for the page.
3131
*/
3232
module.exports = (collections) => {
3333
const authors = authorsCollection(collections);
34+
35+
/** @constant @type {Array<Paginated>} @default */
3436
let paginated = [];
3537

3638
authors.forEach((author) => {

src/site/_includes/components/AuthorsDate.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ const renderAuthorNames = (pairs) => {
6969
}
7070

7171
const inner = pairs
72-
.map(({id, info}) => {
72+
.map(({info}) => {
7373
return html`
74-
<a class="w-author__name-link" href="/authors/${id}/">${info.title}</a>
74+
<a class="w-author__name-link" href="${info.href}">${info.title}</a>
7575
`;
7676
})
7777
.join(', ');
@@ -87,11 +87,15 @@ const renderAuthorNames = (pairs) => {
8787
* Render an authors card, including any number of authors and an optional date.
8888
*
8989
* @param {{authors: !Array<string>, date: ?Date, images: number}} arg
90+
* @param {Object.<string, Author>} [authorsCollection]
9091
* @return {string}
9192
*/
92-
const renderAuthorsDate = ({authors, date = null, images = 2}) => {
93+
const renderAuthorsDate = (
94+
{authors, date = null, images = 2},
95+
authorsCollection,
96+
) => {
9397
const pairs = (authors || []).map((id) => {
94-
const info = contributors[id];
98+
const info = (authorsCollection ? authorsCollection : contributors)[id];
9599
if (!info) {
96100
throw new Error(
97101
`Can't create Author component for "${id}" without contributor ` +

src/site/_includes/components/EventTable.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ const {html} = require('common-tags');
1919
const AuthorsDate = require('./AuthorsDate');
2020

2121
/**
22-
* @param {!Array<{title: string, from: !Date, sessions: !Array}>} event
22+
* @param {!Array<{title: string, from: !Date, sessions: !Array<any>}>} event
23+
* @param {Object.<string, Author>} authorsCollection
2324
* @return {string}
2425
*/
25-
module.exports = (event) => {
26+
module.exports = (event, authorsCollection) => {
2627
// Find the default day to show, as a very basic non-JS fallback. Pick the
2728
// first day where the build time is before the end time of the sessions.
2829
// This isn't a very good fallback as our build happens at minimum of once per
@@ -47,7 +48,7 @@ module.exports = (event) => {
4748
return html`
4849
<tr>
4950
<td class="w-event-schedule__speaker">
50-
${AuthorsDate({authors})}
51+
${AuthorsDate({authors}, authorsCollection)}
5152
</td>
5253
<td class="w-event-schedule__session">${title}</td>
5354
</tr>

src/site/_utils/add-pagination.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ const constants = require('./constants');
1919
/**
2020
* Take array of elements and returns an array of paginated pages for the elements.
2121
* @param {Array<object>} elements Elements to paginate
22-
* @param {{ title: string, href: string, description: string, tag: string }} additionalData Aditional data that may be relevant to a page.
23-
* @return {Array<{ title: string, href: string, description: string, tag: string, posts: Array<object>, index: number, pages: number }>} An array of items to display, including href and index.
22+
* @param {AdditionalData} additionalData Aditional data that may be relevant to a page.
23+
* @return {Array<Paginated>} An array of items to display, including href and index.
2424
*/
2525
module.exports = function addPagination(elements, additionalData = {}) {
2626
if (!Array.isArray(elements)) {

src/site/content/en/authors/feed.njk

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ renderData:
1111
noindex: true
1212
permalink: "/{{lang}}{{ paged.href }}feed.xml"
1313
pagination:
14-
data: collections.authors
14+
data: collections.authorsWithPosts
1515
size: 1
1616
alias: paged
1717
---

src/site/content/en/live/index.njk

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ draft: true
8282
</div>
8383

8484
<div class="w-event-section__column-right w-event-section__column-right__schedule">
85-
{% EventTable event %}
85+
{% EventTable event, collections.authors %}
8686
</div>
8787

8888
</section>

0 commit comments

Comments
 (0)