Skip to content

Commit a2bd8ae

Browse files
authored
Add support for videos to landing pages (#23801)
* Add new video properties frontmatter * Handle video links in the middleware * Video links don't have intros, authors, or full titles * Make videos available from context * Add default video heading * Add basic tests for videos * tmp videos test * Remove stray test debugging * more tmp videos testing * Add videos test fixture * Revert "more tmp videos testing" This reverts commit 382946a5603ff217014797f77f37216bb8bb6c9c. * Revert "tmp videos test" This reverts commit 8767d0eaf08bd4ca04e2dacd12d476a2506c0367.
1 parent 3507dad commit a2bd8ae

6 files changed

Lines changed: 81 additions & 14 deletions

File tree

components/context/ProductLandingContext.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ export const getFeaturedLinksFromReq = (req: any): Record<string, Array<Featured
8787
((entries as Array<any>) || []).map((entry: any) => ({
8888
href: entry.href,
8989
title: entry.title,
90-
intro: entry.intro,
91-
authors: entry.page.authors || [],
92-
fullTitle: entry.fullTitle,
90+
intro: entry.intro || null,
91+
authors: entry.page?.authors || [],
92+
fullTitle: entry.fullTitle || null,
9393
})),
9494
]
9595
})
@@ -141,13 +141,13 @@ export const getProductLandingContextFromRequest = (req: any): ProductLandingCon
141141

142142
featuredArticles: Object.entries(req.context.featuredLinks || [])
143143
.filter(([key]) => {
144-
return key === 'guides' || key === 'popular'
144+
return key === 'guides' || key === 'popular' || key === 'videos'
145145
})
146146
.map(([key, links]: any) => {
147147
return {
148148
label:
149-
key === 'popular'
150-
? req.context.page.featuredLinks.popularHeading || req.context.site.data.ui.toc[key]
149+
key === 'popular' || key === 'videos'
150+
? req.context.page.featuredLinks[key + 'Heading'] || req.context.site.data.ui.toc[key]
151151
: req.context.site.data.ui.toc[key],
152152
viewAllHref:
153153
key === 'guides' && !req.context.currentCategory && hasGuidesPage
@@ -158,9 +158,9 @@ export const getProductLandingContextFromRequest = (req: any): ProductLandingCon
158158
hideIntro: key === 'popular',
159159
href: link.href,
160160
title: link.title,
161-
intro: link.intro,
162-
authors: link.page.authors || [],
163-
fullTitle: link.fullTitle,
161+
intro: link.intro || null,
162+
authors: link.page?.authors || [],
163+
fullTitle: link.fullTitle || null,
164164
}
165165
}),
166166
}

data/ui.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ toc:
3939
popular: Popular
4040
guides: Guides
4141
whats_new: What's new
42+
videos: Videos
4243
pages:
4344
article_version: 'Article version'
4445
miniToc: In this article

lib/frontmatter.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,20 @@ export const schema = {
118118
popularHeading: {
119119
type: 'string',
120120
},
121+
videos: {
122+
type: 'array',
123+
items: {
124+
type: 'object',
125+
properties: {
126+
title: 'string',
127+
href: 'string',
128+
},
129+
},
130+
},
131+
// allows you to use an alternate heading for the videos column
132+
videosHeading: {
133+
type: 'string',
134+
},
121135
},
122136
},
123137
// Shown in `product-landing.html` "What's new" section

middleware/featured-links.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,17 @@ export default async function featuredLinks(req, res, next) {
1616

1717
req.context.featuredLinks = {}
1818
for (const key in req.context.page.featuredLinks) {
19-
req.context.featuredLinks[key] = await getLinkData(
20-
req.context.page.featuredLinks[key],
21-
req.context,
22-
{ title: true, intro: true, fullTitle: true }
23-
)
19+
if (key === 'videos') {
20+
// Videos are external URLs so don't run through getLinkData, they're
21+
// objects with title and href properties.
22+
req.context.featuredLinks[key] = req.context.page.featuredLinks[key]
23+
} else {
24+
req.context.featuredLinks[key] = await getLinkData(
25+
req.context.page.featuredLinks[key],
26+
req.context,
27+
{ title: true, intro: true, fullTitle: true }
28+
)
29+
}
2430
}
2531

2632
return next()
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
title: Article with featuredLinks
3+
versions:
4+
free-pro-team: '*'
5+
featuredLinks:
6+
videos:
7+
- title: codespaces
8+
href: 'https://www.youtube-nocookie.com/embed/cP0I9w2coGU'
9+
- title: more codespaces
10+
href: 'https://www.youtube-nocookie.com/embed/cP0I9w2coGU'
11+
- title: even more codespaces
12+
href: 'https://www.youtube-nocookie.com/embed/cP0I9w2coGU'
13+
videosHeading: Custom Videos heading
14+
layout: product-landing
15+
---

tests/unit/page.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,37 @@ describe('Page class', () => {
532532
})
533533
})
534534

535+
describe('videos', () => {
536+
let page
537+
538+
beforeEach(async () => {
539+
page = await Page.init({
540+
relativePath: 'article-with-videos.md',
541+
basePath: path.join(__dirname, '../fixtures'),
542+
languageCode: 'en',
543+
})
544+
})
545+
546+
it('includes videos specified in the featuredLinks frontmatter', async () => {
547+
expect(page.featuredLinks.videos).toStrictEqual([
548+
{
549+
title: 'codespaces',
550+
href: 'https://www.youtube-nocookie.com/embed/cP0I9w2coGU',
551+
},
552+
{
553+
title: 'more codespaces',
554+
href: 'https://www.youtube-nocookie.com/embed/cP0I9w2coGU',
555+
},
556+
{
557+
title: 'even more codespaces',
558+
href: 'https://www.youtube-nocookie.com/embed/cP0I9w2coGU',
559+
},
560+
])
561+
562+
expect(page.featuredLinks.videosHeading).toBe('Custom Videos heading')
563+
})
564+
})
565+
535566
describe('Page.parseFrontmatter()', () => {
536567
it('throws an error on bad input', () => {
537568
const markdown = null

0 commit comments

Comments
 (0)