diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts index 19515459a656..052437c3dec6 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/authors.test.ts @@ -19,6 +19,7 @@ describe('getBlogPostAuthors', () => { getBlogPostAuthors({ frontMatter: {}, authorsMap: undefined, + baseUrl: '/', }), ).toEqual([]); expect( @@ -27,6 +28,7 @@ describe('getBlogPostAuthors', () => { authors: [], }, authorsMap: undefined, + baseUrl: '/', }), ).toEqual([]); }); @@ -38,6 +40,7 @@ describe('getBlogPostAuthors', () => { author: 'Sébastien Lorber', }, authorsMap: undefined, + baseUrl: '/', }), ).toEqual([{name: 'Sébastien Lorber'}]); expect( @@ -46,6 +49,7 @@ describe('getBlogPostAuthors', () => { authorTitle: 'maintainer', }, authorsMap: undefined, + baseUrl: '/', }), ).toEqual([{title: 'maintainer'}]); expect( @@ -54,8 +58,27 @@ describe('getBlogPostAuthors', () => { authorImageURL: 'https://github.com/slorber.png', }, authorsMap: undefined, + baseUrl: '/', }), ).toEqual([{imageURL: 'https://github.com/slorber.png'}]); + expect( + getBlogPostAuthors({ + frontMatter: { + authorImageURL: '/img/slorber.png', + }, + authorsMap: undefined, + baseUrl: '/', + }), + ).toEqual([{imageURL: '/img/slorber.png'}]); + expect( + getBlogPostAuthors({ + frontMatter: { + authorImageURL: '/img/slorber.png', + }, + authorsMap: undefined, + baseUrl: '/baseURL', + }), + ).toEqual([{imageURL: '/baseURL/img/slorber.png'}]); expect( getBlogPostAuthors({ frontMatter: { @@ -68,6 +91,7 @@ describe('getBlogPostAuthors', () => { authorURL: 'https://github.com/slorber2', }, authorsMap: undefined, + baseUrl: '/', }), ).toEqual([ { @@ -86,8 +110,69 @@ describe('getBlogPostAuthors', () => { authors: 'slorber', }, authorsMap: {slorber: {name: 'Sébastien Lorber'}}, + baseUrl: '/', }), ).toEqual([{key: 'slorber', name: 'Sébastien Lorber'}]); + expect( + getBlogPostAuthors({ + frontMatter: { + authors: 'slorber', + }, + authorsMap: { + slorber: { + name: 'Sébastien Lorber', + imageURL: 'https://github.com/slorber.png', + }, + }, + baseUrl: '/', + }), + ).toEqual([ + { + key: 'slorber', + name: 'Sébastien Lorber', + imageURL: 'https://github.com/slorber.png', + }, + ]); + expect( + getBlogPostAuthors({ + frontMatter: { + authors: 'slorber', + }, + authorsMap: { + slorber: { + name: 'Sébastien Lorber', + imageURL: '/img/slorber.png', + }, + }, + baseUrl: '/', + }), + ).toEqual([ + { + key: 'slorber', + name: 'Sébastien Lorber', + imageURL: '/img/slorber.png', + }, + ]); + expect( + getBlogPostAuthors({ + frontMatter: { + authors: 'slorber', + }, + authorsMap: { + slorber: { + name: 'Sébastien Lorber', + imageURL: '/img/slorber.png', + }, + }, + baseUrl: '/baseUrl', + }), + ).toEqual([ + { + key: 'slorber', + name: 'Sébastien Lorber', + imageURL: '/baseUrl/img/slorber.png', + }, + ]); }); it('can read authors string[]', () => { @@ -100,6 +185,7 @@ describe('getBlogPostAuthors', () => { slorber: {name: 'Sébastien Lorber', title: 'maintainer'}, yangshun: {name: 'Yangshun Tay'}, }, + baseUrl: '/', }), ).toEqual([ {key: 'slorber', name: 'Sébastien Lorber', title: 'maintainer'}, @@ -114,6 +200,7 @@ describe('getBlogPostAuthors', () => { authors: {name: 'Sébastien Lorber', title: 'maintainer'}, }, authorsMap: undefined, + baseUrl: '/', }), ).toEqual([{name: 'Sébastien Lorber', title: 'maintainer'}]); }); @@ -128,6 +215,7 @@ describe('getBlogPostAuthors', () => { ], }, authorsMap: undefined, + baseUrl: '/', }), ).toEqual([ {name: 'Sébastien Lorber', title: 'maintainer'}, @@ -153,6 +241,7 @@ describe('getBlogPostAuthors', () => { slorber: {name: 'Sébastien Lorber', title: 'maintainer'}, yangshun: {name: 'Yangshun Tay', title: 'Yangshun title original'}, }, + baseUrl: '/', }), ).toEqual([ {key: 'slorber', name: 'Sébastien Lorber', title: 'maintainer'}, @@ -173,6 +262,7 @@ describe('getBlogPostAuthors', () => { authors: 'slorber', }, authorsMap: undefined, + baseUrl: '/', }), ).toThrowErrorMatchingInlineSnapshot(` "Can't reference blog post authors by a key (such as 'slorber') because no authors map file could be loaded. @@ -187,6 +277,7 @@ describe('getBlogPostAuthors', () => { authors: 'slorber', }, authorsMap: {}, + baseUrl: '/', }), ).toThrowErrorMatchingInlineSnapshot(` "Can't reference blog post authors by a key (such as 'slorber') because no authors map file could be loaded. @@ -205,6 +296,7 @@ describe('getBlogPostAuthors', () => { yangshun: {name: 'Yangshun Tay'}, jmarcey: {name: 'Joel Marcey'}, }, + baseUrl: '/', }), ).toThrowErrorMatchingInlineSnapshot(` "Blog author with key "slorber" not found in the authors map file. @@ -225,6 +317,7 @@ describe('getBlogPostAuthors', () => { yangshun: {name: 'Yangshun Tay'}, jmarcey: {name: 'Joel Marcey'}, }, + baseUrl: '/', }), ).toThrowErrorMatchingInlineSnapshot(` "Blog author with key "slorber" not found in the authors map file. @@ -245,6 +338,7 @@ describe('getBlogPostAuthors', () => { yangshun: {name: 'Yangshun Tay'}, jmarcey: {name: 'Joel Marcey'}, }, + baseUrl: '/', }), ).toThrowErrorMatchingInlineSnapshot(` "Blog author with key "slorber" not found in the authors map file. @@ -262,6 +356,7 @@ describe('getBlogPostAuthors', () => { author: 'Yangshun Tay', }, authorsMap: undefined, + baseUrl: '/', }), ).toThrowErrorMatchingInlineSnapshot(` "To declare blog post authors, use the 'authors' front matter in priority. @@ -275,6 +370,7 @@ describe('getBlogPostAuthors', () => { author_title: 'legacy title', }, authorsMap: {slorber: {name: 'Sébastien Lorber'}}, + baseUrl: '/', }), ).toThrowErrorMatchingInlineSnapshot(` "To declare blog post authors, use the 'authors' front matter in priority. diff --git a/packages/docusaurus-plugin-content-blog/src/authors.ts b/packages/docusaurus-plugin-content-blog/src/authors.ts index 4d8f7b90b3fb..c5fdad61ddfb 100644 --- a/packages/docusaurus-plugin-content-blog/src/authors.ts +++ b/packages/docusaurus-plugin-content-blog/src/authors.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import {getDataFileData} from '@docusaurus/utils'; +import {getDataFileData, normalizeUrl} from '@docusaurus/utils'; import {Joi, URISchema} from '@docusaurus/utils-validation'; import type {BlogContentPaths} from './types'; import type { @@ -68,17 +68,37 @@ export async function getAuthorsMap(params: { type AuthorsParam = { frontMatter: BlogPostFrontMatter; authorsMap: AuthorsMap | undefined; + baseUrl: string; }; +function normalizeImageUrl({ + imageURL, + baseUrl, +}: { + imageURL: string | undefined; + baseUrl: string; +}) { + return imageURL?.startsWith('/') + ? normalizeUrl([baseUrl, imageURL]) + : imageURL; +} + // Legacy v1/early-v2 front matter fields // We may want to deprecate those in favor of using only frontMatter.authors -function getFrontMatterAuthorLegacy( - frontMatter: BlogPostFrontMatter, -): Author | undefined { +function getFrontMatterAuthorLegacy({ + baseUrl, + frontMatter, +}: { + baseUrl: string; + frontMatter: BlogPostFrontMatter; +}): Author | undefined { const name = frontMatter.author; const title = frontMatter.author_title ?? frontMatter.authorTitle; const url = frontMatter.author_url ?? frontMatter.authorURL; - const imageURL = frontMatter.author_image_url ?? frontMatter.authorImageURL; + const imageURL = normalizeImageUrl({ + imageURL: frontMatter.author_image_url ?? frontMatter.authorImageURL, + baseUrl, + }); if (name || title || url || imageURL) { return { @@ -148,14 +168,26 @@ ${Object.keys(authorsMap) return frontMatterAuthors.map(toAuthor); } +function fixAuthorImageBaseURL( + authors: Author[], + {baseUrl}: {baseUrl: string}, +) { + return authors.map((author) => ({ + ...author, + imageURL: normalizeImageUrl({imageURL: author.imageURL, baseUrl}), + })); +} + export function getBlogPostAuthors(params: AuthorsParam): Author[] { - const authorLegacy = getFrontMatterAuthorLegacy(params.frontMatter); + const authorLegacy = getFrontMatterAuthorLegacy(params); const authors = getFrontMatterAuthors(params); + const updatedAuthors = fixAuthorImageBaseURL(authors, params); + if (authorLegacy) { // Technically, we could allow mixing legacy/authors front matter, but do we // really want to? - if (authors.length > 0) { + if (updatedAuthors.length > 0) { throw new Error( `To declare blog post authors, use the 'authors' front matter in priority. Don't mix 'authors' with other existing 'author_*' front matter. Choose one or the other, not both at the same time.`, @@ -164,5 +196,5 @@ Don't mix 'authors' with other existing 'author_*' front matter. Choose one or t return [authorLegacy]; } - return authors; + return updatedAuthors; } diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index 36028495381c..0a8d2a0e0b67 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -319,7 +319,7 @@ async function processBlogSourceFile( routeBasePath, tagsRouteBasePath, ]); - const authors = getBlogPostAuthors({authorsMap, frontMatter}); + const authors = getBlogPostAuthors({authorsMap, frontMatter, baseUrl}); return { id: slug,