Skip to content

Commit

Permalink
Include examples of components rendered as HTML
Browse files Browse the repository at this point in the history
  • Loading branch information
paulrobertlloyd committed Dec 19, 2023
1 parent 699275d commit 5daf504
Show file tree
Hide file tree
Showing 5 changed files with 323 additions and 69 deletions.
1 change: 0 additions & 1 deletion docs/_components/example/_example.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
}

.app-example__tabs {
// stylelint-disable selector-max-id
.govuk-tabs__panel[id$="-preview"] {
background: govuk-colour("light-grey");
padding: 0;
Expand Down
64 changes: 34 additions & 30 deletions docs/_components/example/template.njk
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
{%- from "govuk/components/tabs/macro.njk" import govukTabs -%}

{%- set nunjucksHtml -%}

```js
{{ getNunjucksCode(params.example) }}
```
{%- endset -%}

{%- set examplePath = "/examples/" + params.example -%}

{%- set previewHtml -%}
<iframe class="app-example__frame" data-module="app-example-frame" src="{{ examplePath | url }}"></iframe>
<p class="app-example__toolbar">
<a class="app-example__new-window" href="{{ examplePath | url }}" target="_blank">Open this example in a new tab</a>
</p>
{%- endset -%}

{{- govukTabs({
classes: "app-example__tabs",
items: [{
label: "Preview",
id: params.example + "-preview",
panel: {
html: previewHtml
}
}, {
label: "Nunjucks",
id: params.example + "-nunjucks",
panel: {
html: nunjucksHtml
}
}]
}) -}}
<div class="govuk-tabs app-example__tabs" data-module="govuk-tabs">
<h2 class="govuk-tabs__title">
Contents
</h2>
<ul class="govuk-tabs__list">
<li class="govuk-tabs__list-item govuk-tabs__list-item--selected">
<a class="govuk-tabs__tab" href="#{{ params.example }}-preview">
Preview
</a>
</li>
<li class="govuk-tabs__list-item">
<a class="govuk-tabs__tab" href="#{{ params.example }}-html">
HTML
</a>
</li>
<li class="govuk-tabs__list-item">
<a class="govuk-tabs__tab" href="#{{ params.example }}-nunjucks">
Nunjucks
</a>
</li>
</ul>
<div class="govuk-tabs__panel" id="{{ params.example }}-preview">
<iframe class="app-example__frame" data-module="app-example-frame" src="{{ examplePath | url }}"></iframe>
<p class="app-example__toolbar">
<a class="app-example__new-window" href="{{ examplePath | url }}" target="_blank">Open this example in a new tab</a>
</p>
</div>
<div class="govuk-tabs__panel govuk-tabs__panel--hidden" id="{{ params.example }}-html">
{{ getHtmlCode(params.example) }}
</div>
<div class="govuk-tabs__panel govuk-tabs__panel--hidden" id="{{ params.example }}-nunjucks">
{{ getNunjucksCode(params.example) }}
</div>
</div>
49 changes: 43 additions & 6 deletions eleventy.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
const fs = require('node:fs')
const govukEleventyPlugin = require('@x-govuk/govuk-eleventy-plugin')
const fs = require('fs')
const beautify = require('js-beautify')
const nunjucks = require('nunjucks')
const matter = require('gray-matter')

const getComponentContent = (componentName) => {
const componentPath = `docs/examples/${componentName}.njk`
const componentFile = fs.readFileSync(componentPath, 'utf-8')
const { content } = matter(componentFile)

return content
}

module.exports = function (eleventyConfig) {
// Plugins
eleventyConfig.addPlugin(govukEleventyPlugin, {
Expand Down Expand Up @@ -50,18 +60,45 @@ module.exports = function (eleventyConfig) {
* This is needed as Nunjucks `include` tag parses included code, and
* currently provides no way to fetch it un-rendered.
* @param {string} componentName - Name of component
* @returns {string} - Rendered Nunjucks template
* @returns {string} - Nunjucks template rendered as raw template
* @see {@link https://github.com/mozilla/nunjucks/issues/788}
*/
eleventyConfig.addNunjucksGlobal('getNunjucksCode', (componentName) => {
const componentPath = `docs/examples/${componentName}.njk`
const componentFile = fs.readFileSync(componentPath, 'utf-8')
const { content } = matter(componentFile)
const content = getComponentContent(componentName)

// Remove `{% from "..." import ... %}` line as this is not needed by users
const nunjucksCode = content.replaceAll(/{%\sfrom\s[^\n]+\n/g, '')

return nunjucksCode
// Use configured Markdown filter to generate syntax highlighted HTML
const markdown = eleventyConfig.getFilter('markdown')
return markdown(`\`\`\`js\n${nunjucksCode}\n\`\`\``)
})

/**
* Fetch Nunjucks code for given `componentName` and return an HTML string.
* @param {string} componentName - Name of component
* @returns {string} - Nunjucks template rendered as HTML
*/
eleventyConfig.addNunjucksGlobal('getHtmlCode', (componentName) => {
const content = getComponentContent(componentName)

// Create Nunjucks environment to render example as HTML
const nunjucksEnv = nunjucks.configure([
'./node_modules/govuk-frontend/dist',
'./node_modules/@x-govuk/govuk-prototype-components'
])
const html = nunjucksEnv.renderString(content).trim()

// Beautify HTML code
const htmlCode = beautify.html(html, {
indent_size: 2,
max_preserve_newlines: 0,
wrap_attributes: 'preserve'
})

// Use configured Markdown filter to generate syntax highlighted HTML
const markdown = eleventyConfig.getFilter('markdown')
return markdown(`\`\`\`html\n${htmlCode}\n\`\`\``)
})

// Collections
Expand Down
Loading

0 comments on commit 5daf504

Please sign in to comment.