diff --git a/.gitignore b/.gitignore index 01c527cf65..4813636df1 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,6 @@ secrets.yml # Local Netlify folder .netlify + +# search index data +search-index.json diff --git a/lib/build-search-index.js b/lib/build-search-index.js new file mode 100644 index 0000000000..f8549f7e0b --- /dev/null +++ b/lib/build-search-index.js @@ -0,0 +1,70 @@ +import fs from 'fs'; +import path from 'path'; +import { globSync } from 'glob'; +import frontMatter from 'front-matter'; +import nunjucks from 'nunjucks'; + +function buildEntries(templatePath, type) { + templatePath = path.resolve(templatePath); + + return { + title: path.basename(templatePath, '.njk'), + uri: templatePath.replace('.njk', '.html').substring(templatePath.indexOf(`/${type}`)), + }; +} + +export default async function buildSearchIndex() { + let types = ['components', 'patterns', 'foundations']; + const pages = []; + types.forEach((type) => { + const hasExample = globSync(`./src/${type}/**/*example-*`).sort(); + const templatePath = Array.from(new Set(hasExample.map((filePath) => path.dirname(filePath)))); + + if (templatePath.length) { + pages.push(...templatePath.map((folderPath) => buildEntries(folderPath, type))); + } + }); + const result = pages.map((page) => { + const path = []; + + return { + en: page.title, + url: page.uri, + category: path.join(' › '), + tags: page.searchTerms?.map((term) => term.title), + }; + }); + const filePath = process.cwd(); + const searchIndexJson = JSON.stringify(result); + fs.writeFile(`${filePath}/src/static/examples/data/search-index.json`, searchIndexJson, (err) => { + if (err) console.log(err); + }); +} + +export function renderSearch(templatePath, nunjucksEnvironment) { + try { + const data = frontMatter(fs.readFileSync(templatePath, { encoding: 'utf8' })); + const layout = data.attributes.layout; + nunjucksEnvironment.addGlobal('isDesignSystemExample', true); + + let template; + if (layout === null) { + template = data.body; + } else { + template = ` + {% extends 'layout/_template.njk' %} + + {% block body %} + ${data.body} + {% endblock %} + `; + } + + const compiledTemplate = nunjucks.compile(template, nunjucksEnvironment, templatePath); + + return compiledTemplate.render(templatePath); + } catch (err) { + console.error(`An error occurred whilst rendering: ${templatePath}`); + throw err; + } +} diff --git a/lib/config.indexPage.js b/lib/config.indexPage.js index bde983bb3f..83ea7d6609 100644 --- a/lib/config.indexPage.js +++ b/lib/config.indexPage.js @@ -1,9 +1,16 @@ +import { renderSearch } from './build-search-index'; +import createNunjucksEnvironment from './create-nunjucks-environment'; + export const pages = [ { title: 'Components', uri: '/components' }, { title: 'Patterns', uri: '/patterns' }, { title: 'Foundations', uri: '/foundations' }, ]; -export const pagesWithIndex = pages.map(page => ({ ...page, uri: `${page.uri}/index.html` })); +export const pagesWithIndex = pages.map((page) => ({ ...page, uri: `${page.uri}/index.html` })); export const title = 'ONS Design System'; + +const nunjucksEnvironment = createNunjucksEnvironment(); +const PROJECT_PATH = process.cwd(); +export const pageSearch = renderSearch(`${PROJECT_PATH}/src/layout/_dsTemplate.njk`, nunjucksEnvironment); diff --git a/lib/dev-server.js b/lib/dev-server.js index 9d73d65769..57e2f3693e 100644 --- a/lib/dev-server.js +++ b/lib/dev-server.js @@ -1,9 +1,9 @@ import cors from 'cors'; import express from 'express'; - import renderPageList from './render-page-list'; import { handleTypeRoute, handleExamplesRoute } from './handle-routes'; -import { pages, title } from './config.indexPage'; +import { pages, title, pageSearch } from './config.indexPage'; +import buildSearchIndex from './build-search-index'; process.env.IS_DEV_SERVER = true; const port = process.env.TEST_PORT ?? 3010; @@ -30,7 +30,8 @@ const port = process.env.TEST_PORT ?? 3010; }); app.get('/', async (req, res) => { - const output = renderPageList(pages, title); + const output = renderPageList(pages, title, pageSearch); + await buildSearchIndex(); res.send(output); }); diff --git a/lib/render-page-list.js b/lib/render-page-list.js index b9a13c1c34..fcaee6428c 100644 --- a/lib/render-page-list.js +++ b/lib/render-page-list.js @@ -1,4 +1,4 @@ -export default function renderPageList(pages, title) { +export default function renderPageList(pages, title, pageSearch = '') { return ` @@ -9,6 +9,7 @@ export default function renderPageList(pages, title) {