@x-govuk/nhsuk-eleventy-plugin 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +22 -0
- package/README.md +35 -0
- package/package.json +102 -0
- package/src/application.js +11 -0
- package/src/application.scss +2 -0
- package/src/components/_index.scss +12 -0
- package/src/components/attribution/_index.scss +13 -0
- package/src/components/blockquote/_index.scss +22 -0
- package/src/components/card-group/macro.njk +3 -0
- package/src/components/card-group/template.njk +26 -0
- package/src/components/code/_index.scss +153 -0
- package/src/components/contents-list/_index.scss +18 -0
- package/src/components/document-header/macro.njk +3 -0
- package/src/components/document-header/template.njk +10 -0
- package/src/components/document-list/macro.njk +3 -0
- package/src/components/document-list/template.njk +22 -0
- package/src/components/footnotes-list/_index.scss +55 -0
- package/src/components/heading/macro.njk +3 -0
- package/src/components/heading/template.njk +15 -0
- package/src/components/hero/_index.scss +17 -0
- package/src/components/hero/macro.njk +3 -0
- package/src/components/hero/template.njk +36 -0
- package/src/components/image/_index.scss +8 -0
- package/src/components/metadata/_index.scss +24 -0
- package/src/components/metadata/macro.njk +3 -0
- package/src/components/metadata/template.njk +50 -0
- package/src/components/prose-scope/_index.scss +72 -0
- package/src/components/prose-scope/macro.njk +3 -0
- package/src/components/prose-scope/template.njk +4 -0
- package/src/components/related/_index.scss +10 -0
- package/src/components/related/macro.njk +3 -0
- package/src/components/related/template.njk +17 -0
- package/src/components/search/_index.scss +120 -0
- package/src/components/search/search.js +133 -0
- package/src/components/sub-navigation/_index.scss +71 -0
- package/src/components/sub-navigation/macro.njk +3 -0
- package/src/components/sub-navigation/template.njk +27 -0
- package/src/data/eleventy-computed.js +17 -0
- package/src/data/options.js +49 -0
- package/src/events/generate-nhsuk-assets.js +57 -0
- package/src/filters/current-page.js +18 -0
- package/src/filters/index.js +21 -0
- package/src/filters/items-from-collection.js +73 -0
- package/src/filters/markdown.js +20 -0
- package/src/index.js +136 -0
- package/src/index.scss +5 -0
- package/src/layouts/base.njk +81 -0
- package/src/layouts/collection.njk +38 -0
- package/src/layouts/error.njk +11 -0
- package/src/layouts/feed.njk +32 -0
- package/src/layouts/hub.njk +31 -0
- package/src/layouts/page.njk +31 -0
- package/src/layouts/post.njk +47 -0
- package/src/layouts/product.njk +32 -0
- package/src/layouts/sitemap.njk +25 -0
- package/src/layouts/sub-navigation.njk +40 -0
- package/src/layouts/tag.njk +14 -0
- package/src/layouts/tags.njk +18 -0
- package/src/markdown-it/alert.js +36 -0
- package/src/markdown-it/deflist.js +16 -0
- package/src/markdown-it/figure.js +12 -0
- package/src/markdown-it/footnote.js +47 -0
- package/src/markdown-it/table.js +18 -0
- package/src/markdown-it.js +91 -0
- package/src/nunjucks.js +65 -0
- package/src/vendor/nhsuk-frontend/_index.scss +2 -0
- package/src/vendor/nhsuk-frontend/components/_index.scss +15 -0
- package/src/vendor/nhsuk-frontend/core/_index.scss +1 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isoDate,
|
|
3
|
+
markdown,
|
|
4
|
+
nhsukDate,
|
|
5
|
+
sliceFromCollection,
|
|
6
|
+
smart
|
|
7
|
+
} from './index.js'
|
|
8
|
+
|
|
9
|
+
function isCollectionData(array) {
|
|
10
|
+
if (!Array.isArray(array) || array.length === 0) {
|
|
11
|
+
return false
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return array.every((item) => {
|
|
15
|
+
return (
|
|
16
|
+
typeof item === 'object' &&
|
|
17
|
+
item !== null &&
|
|
18
|
+
Object.prototype.hasOwnProperty.call(item, 'content') &&
|
|
19
|
+
Object.prototype.hasOwnProperty.call(item, 'data') &&
|
|
20
|
+
Object.prototype.hasOwnProperty.call(item, 'page') &&
|
|
21
|
+
Object.prototype.hasOwnProperty.call(item, 'rawInput')
|
|
22
|
+
)
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getDescriptionHtml(item) {
|
|
27
|
+
let html = ''
|
|
28
|
+
|
|
29
|
+
if (item.date) {
|
|
30
|
+
const classes = item.description
|
|
31
|
+
? 'nhsuk-body-s nhsuk-u-margin-bottom-2'
|
|
32
|
+
: 'nhsuk-body-s'
|
|
33
|
+
|
|
34
|
+
html += `<p class="${classes}"><time class="nhsuk-u-secondary-text-colour" datetime="${isoDate(item.date)}">${nhsukDate(item.date)}</time></p>`
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (item.description) {
|
|
38
|
+
html += `<p class="nhsuk-card__description">${markdown(item.description, 'inline')}</p>`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return html
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Transform list of posts (that may be in a collection) to `items` array that * can be consumed by NHS.UK Frontend card components
|
|
46
|
+
*
|
|
47
|
+
* @param {Array} array - Eleventy collection data
|
|
48
|
+
* @param {number} [n] - Number of items to slice from collection
|
|
49
|
+
* @returns {Array<object>} `items` array
|
|
50
|
+
*/
|
|
51
|
+
export function itemsFromCollection(array, n) {
|
|
52
|
+
if (isCollectionData(array)) {
|
|
53
|
+
array = array.map((item) => {
|
|
54
|
+
return {
|
|
55
|
+
href: item.url,
|
|
56
|
+
date: item.data.date,
|
|
57
|
+
title: item.data.title,
|
|
58
|
+
description: item.data.description,
|
|
59
|
+
image: item.data.image
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
array = array.map((item) => ({
|
|
65
|
+
href: item.href,
|
|
66
|
+
heading: smart(item.title),
|
|
67
|
+
descriptionHtml: getDescriptionHtml(item),
|
|
68
|
+
...(item.image && { imgURL: item.image.src }),
|
|
69
|
+
...(item.image && { imgALT: item.image.alt })
|
|
70
|
+
}))
|
|
71
|
+
|
|
72
|
+
return sliceFromCollection(array, n)
|
|
73
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { normalise } from '@x-govuk/govuk-eleventy-plugin/utils'
|
|
2
|
+
|
|
3
|
+
import { md } from '../markdown-it.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Convert Markdown into NHS.UK Frontend-compliant HTML
|
|
7
|
+
*
|
|
8
|
+
* @param {string} string - Markdown string
|
|
9
|
+
* @param {string} value - If `inline`, renders HTML without paragraph tags
|
|
10
|
+
* @returns {string} HTML
|
|
11
|
+
*/
|
|
12
|
+
export function markdown(string, value) {
|
|
13
|
+
string = normalise(string, '')
|
|
14
|
+
|
|
15
|
+
if (value === 'inline') {
|
|
16
|
+
return md().renderInline(string)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return md().render(string)
|
|
20
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
|
|
3
|
+
import { EleventyHtmlBasePlugin } from '@11ty/eleventy'
|
|
4
|
+
import eleventyNavigation from '@11ty/eleventy-navigation'
|
|
5
|
+
import { addCollections } from '@x-govuk/govuk-eleventy-plugin/collections'
|
|
6
|
+
import { scssExtension } from '@x-govuk/govuk-eleventy-plugin/extensions'
|
|
7
|
+
import {
|
|
8
|
+
FeedTemplate,
|
|
9
|
+
PageNotFoundTemplate,
|
|
10
|
+
SearchIndexTemplate,
|
|
11
|
+
SitemapTemplate,
|
|
12
|
+
TagsTemplate,
|
|
13
|
+
TagTemplate
|
|
14
|
+
} from '@x-govuk/govuk-eleventy-plugin/templates'
|
|
15
|
+
import { getLayoutTemplates } from '@x-govuk/govuk-eleventy-plugin/utils'
|
|
16
|
+
|
|
17
|
+
import { eleventyComputed } from './data/eleventy-computed.js'
|
|
18
|
+
import { defaultPluginOptions } from './data/options.js'
|
|
19
|
+
import { generateAssets } from './events/generate-nhsuk-assets.js'
|
|
20
|
+
import * as filters from './filters/index.js'
|
|
21
|
+
import { md } from './markdown-it.js'
|
|
22
|
+
import { nunjucksConfig } from './nunjucks.js'
|
|
23
|
+
|
|
24
|
+
export const layoutFilenames = [
|
|
25
|
+
'base.njk',
|
|
26
|
+
'collection.njk',
|
|
27
|
+
'error.njk',
|
|
28
|
+
'feed.njk',
|
|
29
|
+
'hub.njk',
|
|
30
|
+
'page.njk',
|
|
31
|
+
'post.njk',
|
|
32
|
+
'product.njk',
|
|
33
|
+
'sitemap.njk',
|
|
34
|
+
'sub-navigation.njk',
|
|
35
|
+
'tag.njk',
|
|
36
|
+
'tags.njk'
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
export const pageFilenames = ['404.md', 'sitemap.md', 'tag.md', 'tags.md']
|
|
40
|
+
|
|
41
|
+
export async function nhsukEleventyPlugin(eleventyConfig, pluginOptions = {}) {
|
|
42
|
+
const { pathPrefix } = eleventyConfig
|
|
43
|
+
|
|
44
|
+
// Plugin options
|
|
45
|
+
const options = defaultPluginOptions(pluginOptions, pathPrefix)
|
|
46
|
+
|
|
47
|
+
// Libraries
|
|
48
|
+
eleventyConfig.setLibrary('md', md(options))
|
|
49
|
+
eleventyConfig.setLibrary('njk', nunjucksConfig(eleventyConfig))
|
|
50
|
+
|
|
51
|
+
// Collections
|
|
52
|
+
await addCollections(eleventyConfig)
|
|
53
|
+
|
|
54
|
+
// Extensions and template formats
|
|
55
|
+
eleventyConfig.addExtension('scss', scssExtension)
|
|
56
|
+
eleventyConfig.addTemplateFormats('scss')
|
|
57
|
+
|
|
58
|
+
// Virtual layout templates
|
|
59
|
+
const baseDirectory = path.join(import.meta.dirname, '..')
|
|
60
|
+
const templates = await getLayoutTemplates(
|
|
61
|
+
eleventyConfig,
|
|
62
|
+
layoutFilenames,
|
|
63
|
+
baseDirectory
|
|
64
|
+
)
|
|
65
|
+
for (const [virtualPath, template] of Object.entries(templates)) {
|
|
66
|
+
eleventyConfig.addTemplate(virtualPath, template)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Virtual page templates
|
|
70
|
+
if (options.templates?.error404) {
|
|
71
|
+
eleventyConfig.addTemplate(
|
|
72
|
+
'404.11ty.js',
|
|
73
|
+
new PageNotFoundTemplate(options.templates?.error404)
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (options.templates?.feed) {
|
|
78
|
+
eleventyConfig.addTemplate(
|
|
79
|
+
'feed.11ty.js',
|
|
80
|
+
new FeedTemplate(options.templates?.feed, {
|
|
81
|
+
url: options?.url
|
|
82
|
+
})
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (options.templates?.searchIndex) {
|
|
87
|
+
eleventyConfig.addTemplate(
|
|
88
|
+
'search-index.11ty.js',
|
|
89
|
+
new SearchIndexTemplate(options.templates.searchIndex)
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (options.templates?.sitemap) {
|
|
94
|
+
eleventyConfig.addTemplate(
|
|
95
|
+
'sitemap.11ty.js',
|
|
96
|
+
new SitemapTemplate(options.templates.sitemap)
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (options.templates?.tags) {
|
|
101
|
+
const slugify = eleventyConfig.getFilter('slugify')
|
|
102
|
+
|
|
103
|
+
eleventyConfig.addTemplate(
|
|
104
|
+
'tags.11ty.js',
|
|
105
|
+
new TagsTemplate(options.templates.tags)
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
eleventyConfig.addTemplate(
|
|
109
|
+
'tag.11ty.js',
|
|
110
|
+
new TagTemplate({ ...options.templates.tags, slugify })
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Filters
|
|
115
|
+
for (const [name, filter] of Object.entries(filters)) {
|
|
116
|
+
eleventyConfig.addFilter(name, filter)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Global data
|
|
120
|
+
eleventyConfig.addGlobalData('options', options)
|
|
121
|
+
eleventyConfig.addGlobalData('eleventyComputed', eleventyComputed)
|
|
122
|
+
|
|
123
|
+
// Passthrough
|
|
124
|
+
eleventyConfig.addPassthroughCopy({
|
|
125
|
+
'node_modules/nhsuk-frontend/dist/nhsuk/assets': 'assets'
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
// Plugins
|
|
129
|
+
eleventyConfig.addPlugin(EleventyHtmlBasePlugin)
|
|
130
|
+
eleventyConfig.addPlugin(eleventyNavigation)
|
|
131
|
+
|
|
132
|
+
// Events
|
|
133
|
+
eleventyConfig.on('eleventy.after', async ({ dir }) => {
|
|
134
|
+
generateAssets(dir, options)
|
|
135
|
+
})
|
|
136
|
+
}
|
package/src/index.scss
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{% extends "nhsuk/template.njk" %}
|
|
2
|
+
|
|
3
|
+
{% set themeColor = options.themeColor | default("#005eb8", true) -%}
|
|
4
|
+
|
|
5
|
+
{#- Set the opengraphImageUrl in parent template to either the one
|
|
6
|
+
from the page metadata or else fallback to the generic one from options. -#}
|
|
7
|
+
{% set opengraphImage = image if image.opengraphImage else opengraphImage %}
|
|
8
|
+
{% set opengraphImageUrl = (opengraphImage.src | canonicalUrl) if opengraphImage else options.opengraphImageUrl %}
|
|
9
|
+
|
|
10
|
+
{# Pagination #}
|
|
11
|
+
{% set pageNumber = pagination.pageNumber + 1 %}
|
|
12
|
+
{% set pageCount = pagination.pages | length %}
|
|
13
|
+
|
|
14
|
+
{# Navigation #}
|
|
15
|
+
{% set breadcrumbItems = collections.all | eleventyNavigationBreadcrumb(eleventyNavigation.key, { includeSelf: includeInBreadcrumbs, allowMissing: true }) | itemsFromNavigation(page.url, options) if eleventyNavigation.key %}
|
|
16
|
+
{% set showBreadcrumbs = options.showBreadcrumbs != false and breadcrumbItems | length > 0 %}
|
|
17
|
+
|
|
18
|
+
{% from "nhsuk/components/breadcrumb/macro.njk" import breadcrumb as nhsukBreadcrumb %}
|
|
19
|
+
{% from "nhsuk/components/footer/macro.njk" import footer as nhsukFooter %}
|
|
20
|
+
{% from "nhsuk/components/header/macro.njk" import header as nhsukHeader %}
|
|
21
|
+
{% from "nhsuk/components/images/macro.njk" import image as nhsukImage %}
|
|
22
|
+
{% from "nhsuk/components/pagination/macro.njk" import pagination as nhsukPagination %}
|
|
23
|
+
|
|
24
|
+
{% from "components/card-group/macro.njk" import appCardGroup with context %}
|
|
25
|
+
{% from "components/document-header/macro.njk" import appDocumentHeader %}
|
|
26
|
+
{% from "components/document-list/macro.njk" import appDocumentList %}
|
|
27
|
+
{% from "components/heading/macro.njk" import appHeading %}
|
|
28
|
+
{% from "components/hero/macro.njk" import appHero with context %}
|
|
29
|
+
{% from "components/metadata/macro.njk" import appMetadata %}
|
|
30
|
+
{% from "components/prose-scope/macro.njk" import appProseScope %}
|
|
31
|
+
{% from "components/related/macro.njk" import appRelated with context %}
|
|
32
|
+
{% from "components/sub-navigation/macro.njk" import appSubNavigation %}
|
|
33
|
+
|
|
34
|
+
{% block headIcons %}
|
|
35
|
+
{%- if options.icons.shortcut %}<link rel="icon" href="{{ options.icons.shortcut }}" sizes="any">{% endif %}
|
|
36
|
+
{%- if options.icons.mask %}<link rel="mask-icon" href="{{ options.icons.mask }}" color="{{ themeColor }}">{% endif %}
|
|
37
|
+
{%- if options.icons.touch %}<link rel="apple-touch-icon" href="{{ options.icons.touch }}">{% endif %}
|
|
38
|
+
{% endblock %}
|
|
39
|
+
|
|
40
|
+
{% block head %}
|
|
41
|
+
<script src="/assets/application.js" type="module"></script>
|
|
42
|
+
|
|
43
|
+
{% for stylesheet in options.stylesheets %}
|
|
44
|
+
<link rel="stylesheet" href="{{ stylesheet }}">
|
|
45
|
+
{% else %}
|
|
46
|
+
<link rel="stylesheet" href="{{ "/assets/application.css" }}">
|
|
47
|
+
{% endfor %}
|
|
48
|
+
|
|
49
|
+
{% if options._feedPath %}<link rel="alternate" type="application/atom+xml" href="{{ options._feedPath }}" >{% endif %}
|
|
50
|
+
|
|
51
|
+
{% if options.url %}<meta property="og:url" content="{{ page.url | canonicalUrl }}">{% endif %}
|
|
52
|
+
<meta property="og:title" content="{{ title }}">
|
|
53
|
+
{% if description %}<meta property="og:description" name="description" content="{{ description | markdown("inline") | striptags(true) }}">{% endif %}
|
|
54
|
+
{% if opengraphImage.src %}<meta name="og:image" content="{{ opengraphImage.src | canonicalUrl }}">
|
|
55
|
+
{% endif %}
|
|
56
|
+
{% if opengraphImage.alt %}<meta property="og:image:alt" content="{{ opengraphImage.alt }}">{% endif %}
|
|
57
|
+
{% endblock %}
|
|
58
|
+
|
|
59
|
+
{% block pageTitle %}
|
|
60
|
+
{{- title if title -}}
|
|
61
|
+
{{- " (page " + pageNumber + " of " + pageCount + ")" if pageCount > 1 -}}
|
|
62
|
+
{{- " - " + options.titleSuffix if options.titleSuffix -}}
|
|
63
|
+
{% endblock %}
|
|
64
|
+
|
|
65
|
+
{% block header %}
|
|
66
|
+
{% if options._searchIndexPath %}
|
|
67
|
+
<app-search index="{{ options._searchIndexPath | htmlBaseUrl }}">
|
|
68
|
+
{{ nhsukHeader(options.header | currentPage(page.url)) }}
|
|
69
|
+
</app-search>
|
|
70
|
+
{% else %}
|
|
71
|
+
{{ nhsukHeader(options.header | currentPage(page.url)) }}
|
|
72
|
+
{% endif %}
|
|
73
|
+
{% endblock %}
|
|
74
|
+
|
|
75
|
+
{% block footer %}
|
|
76
|
+
{{ nhsukFooter(options.footer) }}
|
|
77
|
+
{% endblock %}
|
|
78
|
+
|
|
79
|
+
{% block bodyEnd %}
|
|
80
|
+
{% block scripts %}{% endblock %}
|
|
81
|
+
{% endblock %}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{% extends "layouts/base.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block beforeContent %}
|
|
4
|
+
{{ nhsukBreadcrumb({
|
|
5
|
+
items: breadcrumbItems
|
|
6
|
+
}) if showBreadcrumbs }}
|
|
7
|
+
{% endblock %}
|
|
8
|
+
|
|
9
|
+
{% block content %}
|
|
10
|
+
{{ appDocumentHeader({
|
|
11
|
+
caption: caption,
|
|
12
|
+
title: title,
|
|
13
|
+
description: description
|
|
14
|
+
}) }}
|
|
15
|
+
|
|
16
|
+
{{ appProseScope(content) if content }}
|
|
17
|
+
|
|
18
|
+
{{ appHeading({
|
|
19
|
+
level: 2,
|
|
20
|
+
size: "l",
|
|
21
|
+
title: paginationHeading
|
|
22
|
+
}) if paginationHeading }}
|
|
23
|
+
|
|
24
|
+
{{ appDocumentList({
|
|
25
|
+
headingLevel: 3 if paginationHeading else 2,
|
|
26
|
+
items: pagination.items
|
|
27
|
+
}) }}
|
|
28
|
+
|
|
29
|
+
{{ nhsukPagination({
|
|
30
|
+
classes: "nhsuk-u-reading-width",
|
|
31
|
+
previousUrl: pagination.href.previous,
|
|
32
|
+
previousPage: pagination.page.previous | length + " items",
|
|
33
|
+
nextUrl: pagination.href.next,
|
|
34
|
+
nextPage: pagination.page.next | length + " items"
|
|
35
|
+
}) if pagination.pages.length > 1 }}
|
|
36
|
+
|
|
37
|
+
{{ appRelated(related) if related }}
|
|
38
|
+
{% endblock %}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="{{ options.url }}">
|
|
3
|
+
<title>{{ title or options.homeKey }}</title>
|
|
4
|
+
<link href="{{ page.url | canonicalUrl }}" rel="self"/>
|
|
5
|
+
<link href="{{ options.url }}"/>
|
|
6
|
+
<updated>{{ collections[collection.name] | getNewestCollectionItemDate | dateToRfc3339 }}</updated>
|
|
7
|
+
<id>{{ options.url }}</id>
|
|
8
|
+
{% for item in collections[collection.name] | sliceFromCollection(collection.limit) %}
|
|
9
|
+
{% set absolutePostUrl = item.url | canonicalUrl %}
|
|
10
|
+
<entry>
|
|
11
|
+
<title>{{ item.data.title }}</title>
|
|
12
|
+
<link href="{{ absolutePostUrl }}"/>
|
|
13
|
+
<updated>{{ item.date | dateToRfc3339 }}</updated>
|
|
14
|
+
<id>{{ absolutePostUrl }}</id>
|
|
15
|
+
{% for author in item.data.authors or [item.data.author] %}
|
|
16
|
+
<author>
|
|
17
|
+
<name>{{ author.name }}</name>
|
|
18
|
+
{% if author.url %}
|
|
19
|
+
<uri>{{ author.url }}</uri>
|
|
20
|
+
{% endif %}
|
|
21
|
+
</author>
|
|
22
|
+
{% endfor %}
|
|
23
|
+
<content xml:lang="{{ language or "en" }}" type="html">
|
|
24
|
+
<![CDATA[
|
|
25
|
+
{% if item.data.image %}<figure><img src="{{ item.data.image.src | canonicalUrl }}" alt="{{ item.data.image.alt }}">{% if item.data.image.caption %}<figcaption>{{ item.data.image.caption | markdown }}</figcaption>
|
|
26
|
+
{% endif %}</figure>{% endif %}
|
|
27
|
+
{{- item.templateContent | renderTransforms(item.data.page) }}
|
|
28
|
+
]]>
|
|
29
|
+
</content>
|
|
30
|
+
</entry>
|
|
31
|
+
{% endfor %}
|
|
32
|
+
</feed>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{% extends "layouts/base.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block beforeContent %}
|
|
4
|
+
{{ nhsukBreadcrumb({
|
|
5
|
+
items: breadcrumbItems
|
|
6
|
+
}) if showBreadcrumbs }}
|
|
7
|
+
{% endblock %}
|
|
8
|
+
|
|
9
|
+
{% block content %}
|
|
10
|
+
{{ appDocumentHeader({
|
|
11
|
+
caption: caption,
|
|
12
|
+
title: title,
|
|
13
|
+
description: description
|
|
14
|
+
}) }}
|
|
15
|
+
|
|
16
|
+
{{ appProseScope(content) if content }}
|
|
17
|
+
|
|
18
|
+
{% for group in groups %}
|
|
19
|
+
{{ appHeading({
|
|
20
|
+
level: 2,
|
|
21
|
+
size: "l",
|
|
22
|
+
caption: group.caption,
|
|
23
|
+
title: group.title,
|
|
24
|
+
description: group.description
|
|
25
|
+
}) if group.title }}
|
|
26
|
+
|
|
27
|
+
{{ appCardGroup(group) if group.items }}
|
|
28
|
+
{% endfor %}
|
|
29
|
+
|
|
30
|
+
{{ appRelated(related) if related }}
|
|
31
|
+
{% endblock %}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{% extends "layouts/base.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block beforeContent %}
|
|
4
|
+
{{ nhsukBreadcrumb({
|
|
5
|
+
items: breadcrumbItems
|
|
6
|
+
}) if showBreadcrumbs }}
|
|
7
|
+
{% endblock %}
|
|
8
|
+
|
|
9
|
+
{% block content %}
|
|
10
|
+
{{ appDocumentHeader({
|
|
11
|
+
caption: caption,
|
|
12
|
+
title: title,
|
|
13
|
+
description: description
|
|
14
|
+
}) }}
|
|
15
|
+
|
|
16
|
+
{{ appProseScope(content) if content }}
|
|
17
|
+
|
|
18
|
+
{% if showPagination %}
|
|
19
|
+
{% set previous = collections.navigation | eleventyNavigation(sectionKey or options.homeKey) | getPreviousNavigationItem(page.url) %}
|
|
20
|
+
{% set next = collections.navigation | eleventyNavigation(sectionKey or options.homeKey) | getNextNavigationItem(page.url) %}
|
|
21
|
+
{{ nhsukPagination({
|
|
22
|
+
classes: "nhsuk-u-reading-width",
|
|
23
|
+
previousUrl: previous.url if previous,
|
|
24
|
+
previousPage: previous.title if previous,
|
|
25
|
+
nextUrl: next.url if next,
|
|
26
|
+
nextPage: next.title if next
|
|
27
|
+
}) }}
|
|
28
|
+
{% endif %}
|
|
29
|
+
|
|
30
|
+
{{ appRelated(related) if related }}
|
|
31
|
+
{% endblock %}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{% extends "layouts/base.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block beforeContent %}
|
|
4
|
+
{{ nhsukBreadcrumb({
|
|
5
|
+
items: breadcrumbItems
|
|
6
|
+
}) if showBreadcrumbs }}
|
|
7
|
+
{% endblock %}
|
|
8
|
+
|
|
9
|
+
{% block content %}
|
|
10
|
+
{{ appDocumentHeader({
|
|
11
|
+
caption: caption,
|
|
12
|
+
title: title,
|
|
13
|
+
date: date
|
|
14
|
+
}) }}
|
|
15
|
+
|
|
16
|
+
{{ appMetadata({
|
|
17
|
+
date: date,
|
|
18
|
+
modified: modified,
|
|
19
|
+
author: author,
|
|
20
|
+
tags: tags
|
|
21
|
+
}) }}
|
|
22
|
+
|
|
23
|
+
{% call appProseScope() %}
|
|
24
|
+
{{ nhsukImage({
|
|
25
|
+
classes: "app-image--full",
|
|
26
|
+
src: image.src,
|
|
27
|
+
alt: image.alt,
|
|
28
|
+
caption: image.caption | markdown("inline")
|
|
29
|
+
}) if image }}
|
|
30
|
+
|
|
31
|
+
{{ content }}
|
|
32
|
+
{% endcall %}
|
|
33
|
+
|
|
34
|
+
{% if showPagination %}
|
|
35
|
+
{% set previous = collections.navigation | eleventyNavigation(sectionKey or options.homeKey) | getPreviousNavigationItem(page.url) %}
|
|
36
|
+
{% set next = collections.navigation | eleventyNavigation(sectionKey or options.homeKey) | getNextNavigationItem(page.url) %}
|
|
37
|
+
{{ nhsukPagination({
|
|
38
|
+
classes: "nhsuk-u-reading-width",
|
|
39
|
+
previousUrl: previous.url if previous,
|
|
40
|
+
previousPage: previous.title if previous,
|
|
41
|
+
nextUrl: next.url if next,
|
|
42
|
+
nextPage: next.title if next
|
|
43
|
+
}) }}
|
|
44
|
+
{% endif %}
|
|
45
|
+
|
|
46
|
+
{{ appRelated(related) if related }}
|
|
47
|
+
{% endblock %}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{% extends "layouts/base.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block main %}
|
|
4
|
+
{{ appHero({
|
|
5
|
+
caption: caption,
|
|
6
|
+
title: title,
|
|
7
|
+
headingClasses: headingClasses,
|
|
8
|
+
description: description,
|
|
9
|
+
image: image,
|
|
10
|
+
startButton: startButton
|
|
11
|
+
}) }}
|
|
12
|
+
|
|
13
|
+
<main class="nhsuk-main-wrapper" id="maincontent">
|
|
14
|
+
<div class="nhsuk-width-container">
|
|
15
|
+
{% for group in groups %}
|
|
16
|
+
{{ appHeading({
|
|
17
|
+
level: 2,
|
|
18
|
+
size: "l",
|
|
19
|
+
caption: group.caption,
|
|
20
|
+
title: group.title,
|
|
21
|
+
description: group.description
|
|
22
|
+
}) if group.title }}
|
|
23
|
+
|
|
24
|
+
{{ appCardGroup(group) if group.items }}
|
|
25
|
+
{% endfor %}
|
|
26
|
+
|
|
27
|
+
{{ appProseScope(content) if content }}
|
|
28
|
+
|
|
29
|
+
{{ appRelated(related) if related }}
|
|
30
|
+
</div>
|
|
31
|
+
</main>
|
|
32
|
+
{% endblock %}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{% extends "layouts/base.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block content %}
|
|
4
|
+
{{ appHeading({
|
|
5
|
+
caption: caption,
|
|
6
|
+
title: title,
|
|
7
|
+
description: description
|
|
8
|
+
}) }}
|
|
9
|
+
|
|
10
|
+
{{ appProseScope(content) if content }}
|
|
11
|
+
|
|
12
|
+
{% for item in collections.sitemap | eleventyNavigation(options.homeKey) %}
|
|
13
|
+
<nav class="nhsuk-contents-list">
|
|
14
|
+
<h2 class="nhsuk-heading-m nhsuk-u-margin-bottom-2">
|
|
15
|
+
<a class="nhsuk-link" href="{{ item.url | canonicalUrl | pretty }}">{{ item.title | smart }}</a>
|
|
16
|
+
</h2>
|
|
17
|
+
{% if item.excerpt %}
|
|
18
|
+
<p class="nhsuk-body">{{ item.excerpt | markdown("inline") | striptags(true) }}</p>
|
|
19
|
+
{% endif %}
|
|
20
|
+
{{ collections.sitemap | eleventyNavigation(item.key) | eleventyNavigationToHtml({
|
|
21
|
+
listElement: "ol"
|
|
22
|
+
}) | safe }}
|
|
23
|
+
</nav>
|
|
24
|
+
{% endfor %}
|
|
25
|
+
{% endblock %}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{% extends "layouts/base.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block beforeContent %}
|
|
4
|
+
{{ nhsukBreadcrumb({
|
|
5
|
+
items: breadcrumbItems
|
|
6
|
+
}) if showBreadcrumbs }}
|
|
7
|
+
{% endblock %}
|
|
8
|
+
|
|
9
|
+
{% block content %}
|
|
10
|
+
<div class="nhsuk-grid-row">
|
|
11
|
+
<div class="nhsuk-grid-column-one-quarter">
|
|
12
|
+
{{ appSubNavigation({
|
|
13
|
+
items: collections.navigation | eleventyNavigation(sectionKey or options.homeKey) | itemsFromNavigation(page.url, { pathPrefix: options.pathPrefix }, true)
|
|
14
|
+
}) }}
|
|
15
|
+
</div>
|
|
16
|
+
<div class="nhsuk-grid-column-three-quarters">
|
|
17
|
+
{{ appDocumentHeader({
|
|
18
|
+
caption: caption,
|
|
19
|
+
title: title,
|
|
20
|
+
description: description
|
|
21
|
+
}) }}
|
|
22
|
+
|
|
23
|
+
{{ appProseScope(content) if content }}
|
|
24
|
+
|
|
25
|
+
{% if showPagination %}
|
|
26
|
+
{% set previous = collections.navigation | eleventyNavigation(sectionKey or options.homeKey) | getPreviousNavigationItem(page.url) %}
|
|
27
|
+
{% set next = collections.navigation | eleventyNavigation(sectionKey or options.homeKey) | getNextNavigationItem(page.url) %}
|
|
28
|
+
{{ nhsukPagination({
|
|
29
|
+
classes: "nhsuk-u-reading-width",
|
|
30
|
+
previousUrl: previous.url if previous,
|
|
31
|
+
previousPage: previous.title if previous,
|
|
32
|
+
nextUrl: next.url if next,
|
|
33
|
+
nextPage: next.title if next
|
|
34
|
+
}) }}
|
|
35
|
+
{% endif %}
|
|
36
|
+
|
|
37
|
+
{{ appRelated(related) if related }}
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
{% endblock %}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{% extends "layouts/base.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block content %}
|
|
4
|
+
{{ appHeading({
|
|
5
|
+
caption: caption,
|
|
6
|
+
title: title,
|
|
7
|
+
description: description
|
|
8
|
+
}) }}
|
|
9
|
+
|
|
10
|
+
{{ appDocumentList({
|
|
11
|
+
headingLevel: 3 if paginationHeading else 2,
|
|
12
|
+
items: collections[tag] | reverse
|
|
13
|
+
}) }}
|
|
14
|
+
{% endblock %}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{% extends "layouts/base.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block content %}
|
|
4
|
+
{{ appHeading({
|
|
5
|
+
caption: caption,
|
|
6
|
+
title: title,
|
|
7
|
+
description: description
|
|
8
|
+
}) }}
|
|
9
|
+
|
|
10
|
+
<ul class="nhsuk-list nhsuk-list--bullet">
|
|
11
|
+
{% for tag in collections.tags %}
|
|
12
|
+
<li>
|
|
13
|
+
<a class="nhsuk-link" href="{{ tag | slug }}">{{ tag }}</a>
|
|
14
|
+
({{ collections[tag] | length }})
|
|
15
|
+
</li>
|
|
16
|
+
{% endfor %}
|
|
17
|
+
</ul>
|
|
18
|
+
{% endblock %}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render a GitHub-style alert
|
|
3
|
+
*
|
|
4
|
+
* @param {Function} md - markdown-it instance
|
|
5
|
+
*/
|
|
6
|
+
export function alertRules(md) {
|
|
7
|
+
const { rules } = md.renderer
|
|
8
|
+
|
|
9
|
+
rules.alert_open = function (tokens, idx) {
|
|
10
|
+
const { title, type } = tokens[idx].meta
|
|
11
|
+
|
|
12
|
+
const visuallyHiddenTitle = type.charAt(0).toUpperCase() + type.slice(1)
|
|
13
|
+
const hasCustomTitle = title !== visuallyHiddenTitle
|
|
14
|
+
|
|
15
|
+
if (['caution', 'important', 'warning'].includes(type)) {
|
|
16
|
+
let html = `<div class="nhsuk-warning-callout app-warning-callout--${type}">`
|
|
17
|
+
|
|
18
|
+
// Warning callout always shows a heading, either a custom title,
|
|
19
|
+
// else the type of alert
|
|
20
|
+
html += hasCustomTitle
|
|
21
|
+
? `<h3 class="nhsuk-warning-callout__label"><span class="nhsuk-u-visually-hidden">${visuallyHiddenTitle}: </span>${title}</h3>`
|
|
22
|
+
: `<h3 class="nhsuk-warning-callout__label">${visuallyHiddenTitle}</h3>`
|
|
23
|
+
|
|
24
|
+
return html
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let html = `<div class="nhsuk-inset-text app-inset-text--${type}">`
|
|
28
|
+
|
|
29
|
+
// Inset text only shows a heading if there is a custom title
|
|
30
|
+
html += hasCustomTitle
|
|
31
|
+
? `<h3 class="nhsuk-heading-m"><span class="nhsuk-u-visually-hidden">${visuallyHiddenTitle}: </span>${title}</h3>`
|
|
32
|
+
: `<span class="nhsuk-u-visually-hidden">${visuallyHiddenTitle}: </span>`
|
|
33
|
+
|
|
34
|
+
return html
|
|
35
|
+
}
|
|
36
|
+
}
|