(req, res, next)
| 4 | import { getDeepDataByLanguage } from '../lib/get-data.js' |
| 5 | |
| 6 | export default async function learningTrack(req, res, next) { |
| 7 | const noTrack = () => { |
| 8 | req.context.currentLearningTrack = {} |
| 9 | return next() |
| 10 | } |
| 11 | |
| 12 | if (!req.context.page) return next() |
| 13 | |
| 14 | const trackName = req.query.learn |
| 15 | if (!trackName) return noTrack() |
| 16 | |
| 17 | let trackProduct = req.context.currentProduct |
| 18 | const allLearningTracks = getDeepDataByLanguage('learning-tracks', req.language) |
| 19 | let tracksPerProduct = allLearningTracks[trackProduct] |
| 20 | |
| 21 | // If there are no learning tracks for the current product, try and fall |
| 22 | // back to the learning track product set as a URL parameter. This handles |
| 23 | // the case where a learning track has guide paths for a different product |
| 24 | // than the current learning track product. |
| 25 | if (!tracksPerProduct) { |
| 26 | trackProduct = req.query.learnProduct |
| 27 | tracksPerProduct = allLearningTracks[trackProduct] |
| 28 | } |
| 29 | if (!tracksPerProduct) return noTrack() |
| 30 | |
| 31 | const track = allLearningTracks[trackProduct][trackName] |
| 32 | if (!track) return noTrack() |
| 33 | |
| 34 | // The trackTitle comes from a data .yml file and may use Liquid templating, so we need to render it |
| 35 | const renderOpts = { textOnly: true } |
| 36 | const trackTitle = await renderContent(track.title, req.context, renderOpts) |
| 37 | |
| 38 | const currentLearningTrack = { trackName, trackProduct, trackTitle } |
| 39 | const guidePath = getPathWithoutLanguage(getPathWithoutVersion(req.pagePath)) |
| 40 | |
| 41 | // The raw track.guides will return all guide paths, need to use getLinkData |
| 42 | // so we only get guides available in the current version |
| 43 | const trackGuides = await getLinkData(track.guides, req.context) |
| 44 | |
| 45 | const trackGuidePaths = trackGuides.map((guide) => { |
| 46 | return getPathWithoutLanguage(getPathWithoutVersion(guide.href)) |
| 47 | }) |
| 48 | |
| 49 | let guideIndex = trackGuidePaths.findIndex((path) => path === guidePath) |
| 50 | |
| 51 | // The learning track path may use Liquid version conditionals, handle the |
| 52 | // case where the requested path is a learning track path but won't match |
| 53 | // because of a Liquid conditional. |
| 54 | if (guideIndex < 0) { |
| 55 | guideIndex = await indexOfLearningTrackGuide(trackGuidePaths, guidePath, req.context) |
| 56 | } |
| 57 | |
| 58 | // Also check if the learning track path is now a redirect to the requested |
| 59 | // page, we still want to render the learning track banner in that case. |
| 60 | // Also handles Liquid conditionals in the track path. |
| 61 | if (guideIndex < 0) { |
| 62 | for (const redirect of req.context.page.redirect_from || []) { |
| 63 | if (guideIndex >= 0) break |
nothing calls this directly
no test coverage detected