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
forms-engine-plugin provides two categories of features to help you extend and customise your form journeys beyond the out-of-the-box behaviour.
3
+
forms-engine-plugin provides built-in components and page types you can use immediately in your form definitions, as well as advanced features for driving dynamic behaviour or writing custom code.
A library of built-in form components — text fields, date inputs, radio buttons, file upload, payment, geospatial fields, and more. Add them to your form definition by name.
8
+
9
+
## [Page Types](./features/pages)
10
+
11
+
Built-in page controllers that define how a page behaves — question pages, repeating groups, file upload pages, summary and confirmation pages.
Copy file name to clipboardExpand all lines: docs/getting-started.md
+45-19Lines changed: 45 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,27 +2,27 @@
2
2
3
3
## Foundational knowledge
4
4
5
-
forms-engine-plugin is a hapi plugin for a frontend service, which allows development teams to construct forms using configuration and minimal code. Forms are closely based on the knowledge, components and patterns from the GDS Design System. Forms should remain as lightweight as possible, with business logic being implemented in a backend/BFF API and forms-engine-plugin used as a simple presentation layer.
5
+
forms-engine-plugin is a hapi plugin that lets teams build GOV.UK forms using configuration and minimal code, based on GDS Design System patterns. Keep business logic in a backend/BFF API and treat the plugin as a thin presentation layer.
6
6
7
-
You should aim, wherever possible, to utilise the existing behaviours of forms-engine-plugin. Our team puts a lot of effort into development, user testing and accessibility testing to ensure the forms created with forms-engine-plugin will be of a consistently high quality. Where your team introduces custom behaviour, such as custom components or custom pages, this work will now need to be done by your team. Where possible, favour fixing something upstream in the plugin so many teams can benefit from the work we do. Then, if you still need custom behaviour - go for it! forms-engine-plugin is designed to be extended, just be wise with how you spend your efforts.
7
+
Prefer built-in behaviour wherever possible — it's been developed, user-tested, and accessibility-tested to a consistent standard. If you need something the plugin doesn't support, consider fixing it upstream so all teams benefit. When custom code is genuinely the right call, the plugin is designed to be extended.
8
8
9
-
When developing with forms-engine-plugin, you should favour development using the below priority order. This will ensure your team is writing the minimum amount of code, focusing your efforts on custom code where the requirements are niche and there is value.
9
+
Favour this priority order:
10
10
11
-
1.Use out-of-the box forms-engine-plugin components and page types (components, controllers)
12
-
2.Use configuration-driven advanced functionality to integrate with backends and dynamically change page content (page events, page templates)
13
-
3.Use custom views, custom components and page controllers to implement highly tailored and niche logic (custom Nunjucks, custom Javascript)
11
+
1.Built-in components and page types
12
+
2.Configuration-driven features (page events, templates) to integrate with backends
13
+
3.Custom views, components, and controllers for niche requirements
14
14
15
-
### Contributing back to forms-engine-plugin
15
+
### Contributing back to forms-engine-plugin<!-- no-sidebar -->
16
16
17
-
When you build custom components and page controllers, they might be useful for other teams in Defra to utilise. For example, many teams collect CPH numbers but have no way to validate it's correct. Rather than creating a new CPH number component and letting it sit in your codebase for just your team, see our [contribution guide](./contributing) to learn how to contribute this back to forms-engine-plugin for everyone to benefit from.
17
+
Custom components you build may be useful to other Defra teams. See the [contribution guide](./contributing) to share them upstream rather than keeping them in your own codebase.
18
18
19
19
## Step 1: Add forms-engine-plugin as a dependency
20
20
21
-
### Installation
21
+
### Installation<!-- no-sidebar -->
22
22
23
23
`npm install @defra/forms-engine-plugin --save`
24
24
25
-
### Dependencies
25
+
### Dependencies<!-- no-sidebar -->
26
26
27
27
The following are [plugin dependencies](<https://hapi.dev/api/?v=21.4.0#server.dependency()>) that are required to be registered with hapi:
28
28
@@ -40,7 +40,7 @@ Additional npm dependencies that you will need are:
40
40
-[nunjucks](https://www.npmjs.com/package/nunjucks) - [templating engine](https://mozilla.github.io/nunjucks/) used by GOV.UK design system
41
41
-[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
Forms in forms-engine-plugin are represented by a configuration object called a "form definition". The form definition can be stored in a location and format of your choosing by providing a `formsService` as a registration option. If you are using our 'loader' pattern as recommended in step 2, you will likely be writing YAML or JSON files in your repository as files.
213
+
Forms in forms-engine-plugin are represented by a configuration object called a "form definition". The form definition can be stored in a location and format of your choosing by providing a `formsService` as a registration option. If you are using our 'loader' pattern as recommended in step 2, you will likely be writing YAML or JSON files in your repository.
188
214
189
215
Our examples primarily use JSON. If you are using YAML, simply convert the data structure from JSON to YAML and the examples will still work.
190
216
191
217
The configuration defines several top-level elements:
192
218
193
-
-`pages` - includes a `path`, `title`
219
+
-`pages` - the form journey, each representing a single web page with a path, title, and components
194
220
-`components` - one or more questions on a page
195
-
-`conditions` - used to conditionally show and hide pages and
196
-
-`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/)
221
+
-`conditions` - used to conditionally show and hide pages
222
+
-`lists` - data used 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/)
197
223
198
224
To understand the full set of options available to you, consult our [schema documentation](https://defra.github.io/forms-engine-plugin/schemas/). Specifically, the [form definition schema](https://defra.github.io/forms-engine-plugin/schemas/form-definition-v2-payload-schema).
Copy file name to clipboardExpand all lines: docs/plugin-options.md
+81-27Lines changed: 81 additions & 27 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,29 +2,25 @@
2
2
3
3
The forms plugin is configured with [registration options](https://hapi.dev/api/?v=21.4.0#plugins)
4
4
5
-
## Required options
6
-
7
-
-`nunjucks` (required) - Template engine configuration. See [nunjucks configuration](#nunjucks-configuration)
8
-
-`viewContext` (required) - A function that provides global context to all templates. See [viewContext](#viewcontext)
9
-
-`baseUrl` (required) - Base URL of the application (protocol and hostname, e.g., `"https://myservice.gov.uk"`). Used for generating absolute URLs in markdown rendering and other contexts
10
-
11
-
## Optional options
12
-
13
-
-`model` (optional) - Pre-built `FormModel` instance. When provided, the plugin serves a single static form definition. When omitted, forms are loaded dynamically via `formsService`. See [model](#model)
14
-
-`services` (optional) - object containing `formsService`, `formSubmissionService` and `outputService`
15
-
-`formsService` - used to load `formMetadata` and `formDefinition`
16
-
-`formSubmissionService` - used prepare the form during submission (ignore - subject to change)
17
-
-`outputService` - used to save the submission
18
-
-`controllers` (optional) - Object map of custom page controllers used to override the default. See [custom controllers](#custom-controllers)
19
-
-`globals` (optional) - A map of custom template globals to include. See [custom globals](#custom-globals)
20
-
-`filters` (optional) - A map of custom template filters to include. See [custom filters](#custom-filters)
21
-
-`cache` (optional) - Caching options. Recommended for production. This can be either:
22
-
- a string representing the cache name to use (e.g. hapi's default server cache). See [custom cache](#custom-cache) for more details.
23
-
- a custom `CacheService` instance implementing your own caching logic
24
-
-`pluginPath` (optional) - The location of the plugin (defaults to `node_modules/@defra/forms-engine-plugin`)
25
-
-`preparePageEventRequestOptions` (optional) - A function that will be invoked for http-based [page events](./features/configuration-based/page-events). See [here](./features/configuration-based/page-events#authenticating-a-http-page-event-request-from-forms-engine-plugin-in-your-api) for details
26
-
-`saveAndExit` (optional) - Configuration for custom session management including key generation, session hydration, and persistence. See [save and exit documentation](./features/code-based/save-and-exit) for details
27
-
-`onRequest` (optional) - A function that will be invoked on each request to any form route e.g `/{slug}/{path}`. See [onRequest](#onrequest) for more details
|`nunjucks`| Yes | Template engine configuration. See [Nunjucks configuration](#nunjucks-configuration)|
10
+
|`viewContext`| Yes | A function that provides global context to all templates. See [viewContext](#viewcontext)|
11
+
|`baseUrl`| Yes | Base URL of the application (protocol and hostname, e.g. `"https://myservice.gov.uk"`). Used for generating absolute URLs in markdown rendering and other contexts |
12
+
|`model`| No | Pre-built `FormModel` instance. When provided, the plugin serves a single static form definition. When omitted, forms are loaded dynamically via `formsService`. See [model](#model)|
13
+
|`services`| No | Object containing `formsService`, `formSubmissionService`, and `outputService`. See [services](#services)|
14
+
|`controllers`| No | Object map of custom page controllers used to override the default. See [custom controllers](#custom-controllers)|
15
+
|`globals`| No | A map of custom template globals to include. See [custom globals](#custom-globals)|
16
+
|`filters`| No | A map of custom template filters to include. See [custom filters](#custom-filters)|
17
+
|`cache`| No | Caching options. Recommended for production — either a cache name string or a custom `CacheService` instance. See [custom cache](#custom-cache)|
18
+
|`pluginPath`| No | The location of the plugin. Defaults to `node_modules/@defra/forms-engine-plugin`|
19
+
|`preparePageEventRequestOptions`| No | A function invoked for HTTP-based [page events](./features/configuration-based/page-events) to customise outbound request options |
20
+
|`saveAndExit`| No | Configuration for custom session management. See [save and exit](./features/code-based/save-and-exit)|
21
+
|`onRequest`| No | A function invoked on each request to any form route (e.g. `/{slug}/{path}`). See [onRequest](#onrequest)|
22
+
|`ordnanceSurveyApiKey`| No | Ordnance Survey API key. Required to enable the inline map on geospatial components. See [geospatial map](#geospatial-map)|
23
+
|`ordnanceSurveyApiSecret`| No | Ordnance Survey API secret. Required alongside `ordnanceSurveyApiKey` to enable the inline map on geospatial components |
28
24
29
25
## Option details
30
26
@@ -34,9 +30,50 @@ See [our services documentation](./features/code-based/custom-services).
34
30
35
31
### Custom controllers
36
32
37
-
TODO
33
+
The `controllers` option lets you register custom page controller classes that extend the built-in `PageController`. A custom controller is tied to a page in your form definition by setting the page's `controller` property to the key you register it under.
In your form definition, set the `controller` property of any page to the same key:
64
+
65
+
```json
66
+
{
67
+
"path": "/confirmation",
68
+
"title": "Confirmation",
69
+
"controller": "ConfirmationPageController",
70
+
"components": []
71
+
}
72
+
```
73
+
74
+
When the engine instantiates pages, it first checks for a matching built-in controller, then falls back to the `controllers` map. If no match is found the default `PageController` is used.
75
+
76
+
### Nunjucks configuration
40
77
41
78
The `nunjucks` option is required and configures the template engine paths and layout.
42
79
@@ -184,7 +221,7 @@ In your templates:
184
221
Use the `filter` plugin option to provide custom template filters.
185
222
Filters are available in both [nunjucks](https://mozilla.github.io/nunjucks/templating.html#filters) and [liquid](https://liquidjs.com/filters/overview.html) templates.
186
223
187
-
```
224
+
```js
188
225
constformatter=newIntl.NumberFormat('en-GB')
189
226
190
227
awaitserver.register({
@@ -207,7 +244,7 @@ In production you should create a custom cache one of the available `@hapi/catbo
207
244
208
245
E.g. [Redis](https://github.com/hapijs/catbox-redis)
For detailed documentation and examples, see [Save and Exit](./features/code-based/save-and-exit).
328
+
329
+
### Geospatial map
330
+
331
+
Geospatial components ([Easting Northing](./features/components/easting-northing-field.md), [OS Grid Ref](./features/components/os-grid-ref-field.md), [National Grid Field Number](./features/components/national-grid-field-number-field.md), [Lat Long](./features/components/lat-long-field.md), [Geospatial](./features/components/geospatial-field.md)) render an inline Ordnance Survey map alongside their input fields. The map lets users click a location to auto-populate the coordinate inputs, rather than typing values manually.
332
+
333
+
The map is only activated when both `ordnanceSurveyApiKey` and `ordnanceSurveyApiSecret` are provided at plugin registration. Without them the components still function as plain text inputs.
0 commit comments