(req, res, next)
| 4 | // product, categorie, and map topic TOCs that don't have other layouts specified. |
| 5 | // They are rendered by includes/generic-toc-flat.html or inclueds/generic-toc-nested.html. |
| 6 | export default async function genericToc(req, res, next) { |
| 7 | if (!req.context.page) return next() |
| 8 | if (req.context.currentLayoutName !== 'default') return next() |
| 9 | // This middleware can only run on product, category, and map topics. |
| 10 | if ( |
| 11 | req.context.page.documentType === 'homepage' || |
| 12 | req.context.page.documentType === 'article' || |
| 13 | req.context.page.relativePath === 'search/index.md' |
| 14 | ) |
| 15 | return next() |
| 16 | |
| 17 | // This one product TOC is weird. |
| 18 | const isOneOffProductToc = req.context.page.relativePath === 'github/index.md' |
| 19 | |
| 20 | // There are different types of TOC depending on the document type. |
| 21 | const tocTypes = { |
| 22 | product: 'flat', |
| 23 | category: 'nested', |
| 24 | mapTopic: 'flat', |
| 25 | } |
| 26 | |
| 27 | // Frontmatter can optionally be set on an Early Access product to show hidden child items. |
| 28 | // If so, this is a special case where we want to override the flat tocType and use a nested type. |
| 29 | const earlyAccessToc = req.context.page.earlyAccessToc |
| 30 | |
| 31 | // Find the current TOC type based on the current document type. |
| 32 | const currentTocType = earlyAccessToc ? 'nested' : tocTypes[req.context.page.documentType] |
| 33 | |
| 34 | // Find the part of the site tree that corresponds to the current path. |
| 35 | const treePage = findPageInSiteTree( |
| 36 | req.context.currentProductTree, |
| 37 | req.context.currentEnglishTree, |
| 38 | req.pagePath |
| 39 | ) |
| 40 | |
| 41 | // By default, only include hidden child items on a TOC page if it's an Early Access category or |
| 42 | // map topic page, not a product or 'articles' fake cagegory page (e.g., /early-access/github/articles). |
| 43 | // This is because we don't want entire EA product TOCs to be publicly browseable, but anything at the category |
| 44 | // or below level is fair game because that content is scoped to specific features. |
| 45 | const isCategoryOrMapTopic = |
| 46 | req.context.page.documentType === 'category' || req.context.page.documentType === 'mapTopic' |
| 47 | const isEarlyAccess = req.context.currentPath.includes('/early-access/') |
| 48 | const isArticlesCategory = req.context.currentPath.endsWith('/articles') |
| 49 | |
| 50 | const includeHidden = |
| 51 | earlyAccessToc || (isCategoryOrMapTopic && isEarlyAccess && !isArticlesCategory) |
| 52 | |
| 53 | // Conditionally run getTocItems() recursively. |
| 54 | let isRecursive |
| 55 | // Conditionally render intros. |
| 56 | let renderIntros |
| 57 | |
| 58 | // Get an array of child links with intros and add it to the context object. |
| 59 | if (currentTocType === 'flat' && !isOneOffProductToc) { |
| 60 | isRecursive = false |
| 61 | renderIntros = true |
| 62 | req.context.genericTocFlat = await getTocItems(treePage, req.context, { |
| 63 | recurse: isRecursive, |
nothing calls this directly
no test coverage detected