Skip to content

Commit 2c92c49

Browse files
authored
Expose document type for articles in API (#60109)
1 parent 2029096 commit 2c92c49

File tree

4 files changed

+52
-6
lines changed

4 files changed

+52
-6
lines changed

src/article-api/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ Get article metadata and content in a single object. Equivalent to calling `/art
6868
"meta": {
6969
"title": "About GitHub and Git",
7070
"intro": "You can use GitHub and Git to collaborate on work.",
71-
"product": "Get started"
71+
"product": "Get started",
72+
"documentType": "article"
7273
},
7374
"body": "## About GitHub\n\nGitHub is a cloud-based platform where you can store, share, and work together with others to write code.\n\nStoring your code in a \"repository\" on GitHub allows you to:\n\n* **Showcase or share** your work.\n [...]"
7475
}
@@ -111,7 +112,7 @@ Get metadata about an article.
111112
**Parameters**:
112113
- **pathname** (string) - Article path (e.g. '/en/get-started/article-name')
113114

114-
**Returns**: (object) - JSON object containing article metadata with title, intro, and product information.
115+
**Returns**: (object) - JSON object containing article metadata with title, intro, product, and documentType information.
115116

116117
**Throws**:
117118
- (Error): 400 - If pathname parameter is invalid.
@@ -124,6 +125,7 @@ Get metadata about an article.
124125
"title": "About GitHub and Git",
125126
"intro": "You can use GitHub and Git to collaborate on work.",
126127
"product": "Get started",
128+
"documentType": "article",
127129
"breadcrumbs": [
128130
{
129131
"href": "/en/get-started",

src/article-api/middleware/article-pageinfo.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,14 @@ export async function getMetadata(req: ExtendedRequestWithPageInfo) {
135135
// So by the time we get here, the pathname should be one of the
136136
// page's valid permalinks.
137137
const { page, pathname, archived } = req.pageinfo
138+
const documentType = page?.documentType ?? null
138139

139140
if (archived && archived.isArchived) {
140141
const { requestedVersion } = archived
141142
const title = `GitHub Enterprise Server ${requestedVersion} Help Documentation`
142143
const intro = ''
143144
const product = 'GitHub Enterprise Server'
144-
return { meta: { intro, title, product } }
145+
return { meta: { intro, title, product, documentType } }
145146
}
146147

147148
if (!page) {
@@ -156,5 +157,5 @@ export async function getMetadata(req: ExtendedRequestWithPageInfo) {
156157
const fromCache = await getPageInfoFromCache(page, pathname)
157158
const { cacheInfo, ...meta } = fromCache
158159

159-
return { meta, cacheInfo }
160+
return { meta: { ...meta, documentType }, cacheInfo }
160161
}

src/article-api/middleware/article.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ const router = express.Router()
3939
* "meta": {
4040
* "title": "About GitHub and Git",
4141
* "intro": "You can use GitHub and Git to collaborate on work.",
42-
* "product": "Get started"
42+
* "product": "Get started",
43+
* "documentType": "article"
4344
* },
4445
* "body": "## About GitHub\n\nGitHub is a cloud-based platform where you can store, share, and work together with others to write code.\n\nStoring your code in a \"repository\" on GitHub allows you to:\n\n* **Showcase or share** your work.\n [...]"
4546
* }
@@ -112,7 +113,7 @@ router.get(
112113
* Get metadata about an article.
113114
* @route GET /api/article/meta
114115
* @param {string} pathname - Article path (e.g. '/en/get-started/article-name')
115-
* @returns {object} JSON object containing article metadata with title, intro, and product information.
116+
* @returns {object} JSON object containing article metadata with title, intro, product, and documentType information.
116117
* @throws {Error} 400 - If pathname parameter is invalid.
117118
* @throws {Error} 404 - If the path is valid, but the page couldn't be resolved.
118119
* @example
@@ -121,6 +122,7 @@ router.get(
121122
* "title": "About GitHub and Git",
122123
* "intro": "You can use GitHub and Git to collaborate on work.",
123124
* "product": "Get started",
125+
* "documentType": "article",
124126
* "breadcrumbs": [
125127
* {
126128
* "href": "/en/get-started",

src/article-api/tests/pageinfo.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ interface PageMetadata {
1111
product: string
1212
title: string
1313
intro: string
14+
documentType: string | null
1415
}
1516

1617
interface ErrorResponse {
@@ -44,6 +45,7 @@ describe('pageinfo api', () => {
4445
expect(meta.intro).toBe(
4546
'Get started using HubGit to manage Git repositories and collaborate with others.',
4647
)
48+
expect(meta.documentType).toBe('category')
4749
// Check that it can be cached at the CDN
4850
expect(res.headers['set-cookie']).toBeUndefined()
4951
expect(res.headers['cache-control']).toContain('public')
@@ -170,6 +172,44 @@ describe('pageinfo api', () => {
170172
}
171173
})
172174

175+
test('documentType for different page types', async () => {
176+
// Homepage
177+
{
178+
const res = await get(makeURL('/en'))
179+
expect(res.statusCode).toBe(200)
180+
const meta = JSON.parse(res.body) as PageMetadata
181+
expect(meta.documentType).toBe('homepage')
182+
}
183+
// Product
184+
{
185+
const res = await get(makeURL('/en/get-started'))
186+
expect(res.statusCode).toBe(200)
187+
const meta = JSON.parse(res.body) as PageMetadata
188+
expect(meta.documentType).toBe('product')
189+
}
190+
// Category
191+
{
192+
const res = await get(makeURL('/en/get-started/start-your-journey'))
193+
expect(res.statusCode).toBe(200)
194+
const meta = JSON.parse(res.body) as PageMetadata
195+
expect(meta.documentType).toBe('category')
196+
}
197+
// Subcategory
198+
{
199+
const res = await get(makeURL('/en/actions/category/subcategory'))
200+
expect(res.statusCode).toBe(200)
201+
const meta = JSON.parse(res.body) as PageMetadata
202+
expect(meta.documentType).toBe('subcategory')
203+
}
204+
// Article
205+
{
206+
const res = await get(makeURL('/en/get-started/start-your-journey/hello-world'))
207+
expect(res.statusCode).toBe(200)
208+
const meta = JSON.parse(res.body) as PageMetadata
209+
expect(meta.documentType).toBe('article')
210+
}
211+
})
212+
173213
test('archived enterprise versions', async () => {
174214
// For example /en/enterprise-server@3.8 is a valid Page in the
175215
// site tree, but /en/enterprise-server@2.6 is not. Yet we can
@@ -182,6 +222,7 @@ describe('pageinfo api', () => {
182222
expect(res.statusCode).toBe(200)
183223
const meta = JSON.parse(res.body) as PageMetadata
184224
expect(meta.title).toMatch('GitHub Enterprise Server 3.2 Help Documentation')
225+
expect(meta.documentType).toBeNull()
185226
}
186227

187228
// The oldest known archived version that we proxy

0 commit comments

Comments
 (0)