You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Move pull request template to .github/
* Split out readme into docs/* folder
* Organise README.md into docs/
* Fix broken link to getting started page
* fix typo
* Add link to getting started guide
* Move features into feature folder
* Add link to custom services page
* update
* add documentation for page templates
* add link to contribution guide
* Add page events documentation
* add foundational knowledge
* condense for brevity
* fix broken link
* fix hierarchy
* fix broken link
* Add future of page event authentication to docs
* Fix typo in PAGE_EVENTS
* Indent PAGE_TEMPLATE example
* Fix auth PAGE_TEMPLATE example
* Fix typo in PAGE_TEMPLATE
* use jinja2 not jinja in code block header
* grammar fix
* Switch to jsonc
* more typo fixes
---------
Co-authored-by: David Stone <davidjamesstone@gmail.com>
-[@hapi/vision](https://github.com/hapijs/vision) - Template rendering support
48
-
49
-
Additional npm dependencies that you will need are:
50
-
51
-
`npm install nunjucks govuk-frontend --save`
52
-
53
-
-[nunjucks](https://www.npmjs.com/package/nunjucks) - [templating engine](https://mozilla.github.io/nunjucks/) used by GOV.UK design system
54
-
-[govuk-frontend](https://www.npmjs.com/package/govuk-frontend) - [code](https://github.com/alphagov/govuk-frontend) you need to build a user interface for government platforms and services
55
-
56
-
Optional dependencies
57
-
58
-
`npm install @hapi/inert --save`
59
-
60
-
-[@hapi/inert](https://www.npmjs.com/package/@hapi/inert) - static file and directory handlers for serving GOV.UK assets and styles
61
-
62
-
## Setup
63
-
64
-
### Form config
65
-
66
-
The `form-engine-plugin` uses JSON configuration files to serve form journeys.
67
-
These files are called `Form definitions` and are built up of:
68
-
69
-
-`pages` - includes a `path`, `title`
70
-
-`components` - one or more questions on a page
71
-
-`conditions` - used to conditionally show and hide pages and
72
-
-`lists` - data used to in selection fields like [Select](https://design-system.service.gov.uk/components/select/), [Checkboxes](https://design-system.service.gov.uk/components/checkboxes/) and [Radios](https://design-system.service.gov.uk/components/radios/)
73
-
74
-
The [types](https://github.com/DEFRA/forms-designer/blob/main/model/src/form/form-definition/types.ts), `joi`[schema](https://github.com/DEFRA/forms-designer/blob/main/model/src/form/form-definition/index.ts) and the [examples](test/form/definitions) folder are a good place to learn about the structure of these files.
75
-
76
-
TODO - Link to wiki for `Form metadata`
77
-
TODO - Link to wiki for `Form definition`
78
-
79
-
#### Providing form config to the engine
80
-
81
-
The engine plugin registers several [routes](https://hapi.dev/tutorials/routing/?lang=en_US) on the hapi server.
82
-
83
-
They look like this:
84
-
85
-
```
86
-
GET /{slug}/{path}
87
-
POST /{slug}/{path}
88
-
```
89
-
90
-
A unique `slug` is used to route the user to the correct form, and the `path` used to identify the correct page within the form to show.
91
-
The [plugin registration options](#options) have a `services` setting to provide a `formsService` that is responsible for returning `form definition` data.
92
-
93
-
WARNING: This below is subject to change
94
-
95
-
A `formsService` has two methods, one for returning `formMetadata` and another to return `formDefinition`s.
96
-
97
-
```
98
-
const formsService = {
99
-
getFormMetadata: async function (slug) {
100
-
// Returns the metadata for the slug
101
-
},
102
-
getFormDefinition: async function (id, state) {
103
-
// Returns the form definition for the given id
104
-
}
105
-
}
106
-
```
107
-
108
-
The reason for the two separate methods is caching.
109
-
`formMetadata` is a lightweight record designed to give top level information about a form.
110
-
This method is invoked for every page request.
111
-
112
-
Only when the `formMetadata` indicates that the definition has changed is a call to `getFormDefinition` is made.
113
-
The response from this can be quite big as it contains the entire form definition.
114
-
115
-
See [example](#example) below for more detail
116
-
117
-
### Static assets and styles
118
-
119
-
TODO
120
-
121
-
## Example
122
-
123
-
```
124
-
import hapi from '@hapi/hapi'
125
-
import yar from '@hapi/yar'
126
-
import crumb from '@hapi/crumb'
127
-
import inert from '@hapi/inert'
128
-
import pino from 'hapi-pino'
129
-
import plugin from '@defra/forms-engine-plugin'
130
-
131
-
const server = hapi.server({
132
-
port: 3000
133
-
})
134
-
135
-
// Register the dependent plugins
136
-
await server.register(pino)
137
-
await server.register(inert)
138
-
await server.register(crumb)
139
-
await server.register({
140
-
plugin: yar,
141
-
options: {
142
-
cookieOptions: {
143
-
password: 'ENTER_YOUR_SESSION_COOKIE_PASSWORD_HERE' // Must be > 32 chars
144
-
}
145
-
}
146
-
})
147
-
148
-
// Register the `forms-engine-plugin`
149
-
await server.register({
150
-
plugin
151
-
})
152
-
153
-
await server.start()
154
-
```
155
-
156
-
## Environment variables
157
-
158
-
## Options
159
-
160
-
The forms plugin is configured with [registration options](https://hapi.dev/api/?v=21.4.0#plugins)
161
-
162
-
-`services` (optional) - object containing `formsService`, `formSubmissionService` and `outputService`
163
-
-`formsService` - used to load `formMetadata` and `formDefinition`
164
-
-`formSubmissionService` - used prepare the form during submission (ignore - subject to change)
165
-
-`outputService` - used to save the submission
166
-
-`controllers` (optional) - Object map of custom page controllers used to override the default. See [custom controllers](#custom-controllers)
167
-
-`filters` (optional) - A map of custom template filters to include
168
-
-`cacheName` (optional) - The cache name to use. Defaults to hapi's [default server cache]. Recommended for production. See [here]
169
-
(#custom-cache) for more details
170
-
-`viewPaths` (optional) - Include additional view paths when using custom `page.view`s
171
-
-`pluginPath` (optional) - The location of the plugin (defaults to `node_modules/@defra/forms-engine-plugin`)
172
-
173
-
### Services
174
-
175
-
TODO
176
-
177
-
### Custom controllers
178
-
179
-
TODO
180
-
181
-
### Custom filters
182
-
183
-
Use the `filter` plugin option to provide custom template filters.
184
-
Filters are available in both [nunjucks](https://mozilla.github.io/nunjucks/templating.html#filters) and [liquid](https://liquidjs.com/filters/overview.html) templates.
185
-
186
-
```
187
-
const formatter = new Intl.NumberFormat('en-GB')
188
-
189
-
await server.register({
190
-
plugin,
191
-
options: {
192
-
filters: {
193
-
money: value => formatter.format(value),
194
-
upper: value => typeof value === 'string' ? value.toUpperCase() : value
195
-
}
196
-
}
197
-
})
198
-
```
199
-
200
-
### Custom cache
201
-
202
-
The plugin will use the [default server cache](https://hapi.dev/api/?v=21.4.0#-serveroptionscache) to store form answers on the server.
203
-
This is just an in-memory cache which is fine for development.
204
-
205
-
In production you should create a custom cache one of the available `@hapi/catbox` adapters.
206
-
207
-
E.g. [Redis](https://github.com/hapijs/catbox-redis)
208
-
209
-
```
210
-
import { Engine as CatboxRedis } from '@hapi/catbox-redis'
211
-
212
-
const server = new Hapi.Server({
213
-
cache : [
214
-
{
215
-
name: 'my_cache',
216
-
provider: {
217
-
constructor: CatboxRedis,
218
-
options: {}
219
-
}
220
-
}
221
-
]
222
-
})
223
-
```
224
-
225
-
## Exemplar
19
+
## Demo of DXT
226
20
227
21
TODO: Link to CDP exemplar
228
22
229
-
## Templates
230
-
231
-
The following elements support [LiquidJS templates](https://liquidjs.com/):
232
-
233
-
- Page **title**
234
-
- Form component **title**
235
-
- Support for fieldset legend text or label text
236
-
- This includes when the title is used in **error messages**
237
-
- Html (guidance) component **content**
238
-
- Summary component **row** key title (check answers and repeater summary)
239
-
240
-
### Template Data
241
-
242
-
The data the templates are evaluated against is the raw answers the user has provided up to the page they're currently on.
243
-
For example, given a YesNoField component called `TKsWbP`, the template `{{ TKsWbP }}` would render "true" or "false" depending on how the user answered the question.
244
-
245
-
The current FormContext is also available as `context` in the templates. This allows access to the full data including the path the user has taken in their journey and any miscellaneous data returned from `Page event`s in `context.data`.
246
-
247
-
### Liquid Filters
248
-
249
-
There are a number of `LiquidJS` filters available to you from within the templates:
250
-
251
-
-`page` - returns the page definition for the given path
252
-
-`field` - returns the component definition for the given name
253
-
-`href` - returns the page href for the given page path
254
-
-`answer` - returns the user's answer for a given component
255
-
-`evaluate` - evaluates and returns a Liquid template using the current context
256
-
257
-
### Examples
258
-
259
-
```json
260
-
"pages": [
261
-
{
262
-
"title": "What's your name?",
263
-
"path": "/full-name",
264
-
"components": [
265
-
{
266
-
"name": "WmHfSb",
267
-
"title": "What's your full name?",
268
-
"type": "TextField"
269
-
}
270
-
]
271
-
},
272
-
// This example shows how a component can use an answer to a previous question (What's your full name) in it's title
273
-
{
274
-
"title": "Are you in England?",
275
-
"path": "/are-you-in-england",
276
-
"components": [
277
-
{
278
-
"name": "TKsWbP",
279
-
"title": "Are you in England, {{ WmHfSb }}?",
280
-
"type": "YesNoField"
281
-
}
282
-
]
283
-
},
284
-
// This example shows how a Html (guidance) component can use the available filters to get the form definition and user answers and display them
285
-
{
286
-
"title": "Template example for {{ WmHfSb }}?",
287
-
"path": "/example",
288
-
"components": [
289
-
{
290
-
"title": "Html",
291
-
"type": "Html",
292
-
"content": "<p class=\"govuk-body\">
293
-
// Use Liquid's `assign` to create a variable that holds reference to the \"/are-you-in-england\" page
// Use the href filter to display the full page path
300
-
{{ \"/are-you-in-england\" | href }}<br>
301
-
302
-
// Use the `answer` filter to render the user provided answer to a question
303
-
{{ 'TKsWbP' | answer }}
304
-
</p>\n"
305
-
}
306
-
]
307
-
}
308
-
]
309
-
```
310
-
311
-
## Templates and views
312
-
313
-
### Extending the default layout
314
-
315
-
TODO
316
-
317
-
To override the default page template, vision and nunjucks both need to be configured to search in the `forms-engine-plugin` views directory when looking for template files.
23
+
## Installation
318
24
319
-
For vision this is done through the `path`[plugin option](https://github.com/hapijs/vision/blob/master/API.md#options)
320
-
For nunjucks it is configured through the environment [configure options](https://mozilla.github.io/nunjucks/api.html#configure).
25
+
[See our getting started developer guide](./docs/GETTING_STARTED.md).
321
26
322
-
The `forms-engine-plugin` path to add can be imported from:
27
+
## Documentation
323
28
324
-
`import { VIEW_PATH } from '@defra/forms-engine-plugin'`
29
+
DXT has a mix of configuration-driven and code-based features that developers can utilise.
325
30
326
-
Which can then be appended to the `node_modules` path `node_modules/@defra/forms-engine`.
31
+
[See our documentation folder](./docs/INDEX.md)to learn more about the features of DXT.
327
32
328
-
The main template layout is `govuk-frontend`'s `template.njk` file, this also needs to be added to the `path`s that nunjucks can look in.
Our GitHub Actions workflow (`publish.yml`) is set up to make publishing a breeze, using semantic versioning and a variety of release strategies. Here's how you can make the most of it:
Copy file name to clipboardExpand all lines: docs/CONTRIBUTING.md
+7-7Lines changed: 7 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,13 +7,13 @@ Thank you for considering making a contribution to DXT! Our goal is to make DXT
7
7
8
8
This guide aims to set clear expectations for everyone involved in our project, to make collaborating a smooth and enjoyable experience.
9
9
10
-
# I have a question
10
+
##I have a question
11
11
12
12
If you are within Department for Environment, Food & Rural Affairs, please primarily direct your questions to our Slack channel [#defra-forms-support](https://defra-digital-team.slack.com). Our team monitors this channel during working hours and will provide assistance.
13
13
14
-
# I want to request something
14
+
##I want to request something
15
15
16
-
## Reporting bugs
16
+
###Reporting bugs
17
17
18
18
Report bugs on the [#defra-forms-support](https://defra-digital-team.slack.com) slack channel. If you are not a member of Defra, [submit a GitHub issue](https://github.com/DEFRA/forms-engine-plugin/issues).
19
19
@@ -36,11 +36,11 @@ If your bug is with the plugin, ensure you are running the plugin in a supported
36
36
- An estimated timeframe for a resolution
37
37
- An update once the issue is resolved
38
38
39
-
## Suggesting features
39
+
###Suggesting features
40
40
41
41
Feature suggestions are welcomed from teams within Defra Group only. Our roadmap is continually updated as new requirements emerge. Suggest new features on our [#defra-forms-support](https://defra-digital-team.slack.com) slack channel.
42
42
43
-
# I want to contribute something
43
+
##I want to contribute something
44
44
45
45
All code contributed to this repository should meet the [Defra software development standards](https://defra.github.io/software-development-standards/). Our codebase, by exception, allows modification of Typescript files where appropriate. However, new code that is contributed should be Javascript with types via JSDoc, not Typescript.
46
46
@@ -50,10 +50,10 @@ Our GitHub Workflows will mark each pull request with a pass/fail based on tests
50
50
51
51
Draft pull requests are accepted if you are not yet finished, but would like early feedback. Pull requests that remain as a draft for over 30 days will be closed.
52
52
53
-
## Fixing bugs
53
+
###Fixing bugs
54
54
55
55
If you would like to fix the bug yourself, contributions are accepted through pull requests.
56
56
57
-
## Adding features
57
+
###Adding features
58
58
59
59
Features should be discussed with the Defra Forms team prior to implementation. This is to prevent wasted effort if the Defra Forms team decides not to accept it, or if we suggest any significant amendments. Reach out to us on [#defra-forms-support](https://defra-digital-team.slack.com) to discuss your requirements. If accepted by the product owner, we welcome a pull request.
0 commit comments