From 8500f050ae2c3954d5018953b9c644c090c6d2d6 Mon Sep 17 00:00:00 2001 From: Mohammed Khalid Date: Fri, 17 Oct 2025 12:23:34 +0100 Subject: [PATCH] chore(docs): PLUGIN_OPTIONS documentation with required and optional options, including detailed explanations for nunjucks configuration, viewContext, and model usage. Add examples for clarity. --- docs/PLUGIN_OPTIONS.md | 165 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 158 insertions(+), 7 deletions(-) diff --git a/docs/PLUGIN_OPTIONS.md b/docs/PLUGIN_OPTIONS.md index 4a5421ff7..b74fa6c34 100644 --- a/docs/PLUGIN_OPTIONS.md +++ b/docs/PLUGIN_OPTIONS.md @@ -9,21 +9,29 @@ nav_order: 3 The forms plugin is configured with [registration options](https://hapi.dev/api/?v=21.4.0#plugins) +## Required options + +- `nunjucks` (required) - Template engine configuration. See [nunjucks configuration](#nunjucks-configuration) +- `viewContext` (required) - A function that provides global context to all templates. See [viewContext](#viewcontext) +- `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 + +## Optional options + +- `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) - `services` (optional) - object containing `formsService`, `formSubmissionService` and `outputService` - `formsService` - used to load `formMetadata` and `formDefinition` - `formSubmissionService` - used prepare the form during submission (ignore - subject to change) - `outputService` - used to save the submission - `controllers` (optional) - Object map of custom page controllers used to override the default. See [custom controllers](#custom-controllers) -- `globals` (optional) - A map of custom template globals to include -- `filters` (optional) - A map of custom template filters to include -- `cache` (optional) - Caching options - - `cache` (optional) - Caching options. Recommended for production. This can be either: - - a string representing the cache name to use (e.g. hapi's default server cache). See [here](#custom-cache) for more details. - - a custom `CacheService` instance implementing your own caching logic +- `globals` (optional) - A map of custom template globals to include. See [custom globals](#custom-globals) +- `filters` (optional) - A map of custom template filters to include. See [custom filters](#custom-filters) +- `cache` (optional) - Caching options. Recommended for production. This can be either: + - a string representing the cache name to use (e.g. hapi's default server cache). See [custom cache](#custom-cache) for more details. + - a custom `CacheService` instance implementing your own caching logic - `pluginPath` (optional) - The location of the plugin (defaults to `node_modules/@defra/forms-engine-plugin`) - `preparePageEventRequestOptions` (optional) - A function that will be invoked for http-based [page events](./features/configuration-based/PAGE_EVENTS.md). See [here](./features/configuration-based/PAGE_EVENTS.md#authenticating-a-http-page-event-request-from-dxt-in-your-api) for details - `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.md) for details -- `onRequest` (optional) - A function that will be invoked on each request to any form route e.g `/{slug}/{path}`. See [here](#onrequest) for more details +- `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 ## Services @@ -33,6 +41,149 @@ See [our services documentation](./features/code-based/CUSTOM_SERVICES.md). TODO +## nunjucks configuration + +The `nunjucks` option is required and configures the template engine paths and layout. + +```ts +{ + baseLayoutPath: string // Path to the base layout template + paths: string[] // Array of paths to search for Nunjucks templates +} +``` + +Example: + +```js +await server.register({ + plugin, + options: { + nunjucks: { + baseLayoutPath: 'layout.html', + paths: [ + 'src/server/views', + 'node_modules/govuk-frontend/dist' + ] + } + } +}) +``` + +The `baseLayoutPath` is the file that all form pages will extend. The `paths` array tells Nunjucks where to look for templates, including your custom templates and any third-party template libraries (like GOV.UK Frontend). + +## viewContext + +The `viewContext` option is a required function that provides global context variables to all templates rendered by the plugin. + +```ts +type ViewContext = ( + request: AnyFormRequest | null +) => Record | Promise> +``` + +This function receives the current request (or `null` for non-request contexts) and should return an object containing any data you want available in your templates, such as: + +- Application version +- Asset paths +- Configuration values +- CSRF tokens +- User session data +- Feature flags + +Example: + +```js +import pkg from './package.json' with { type: 'json' } + +await server.register({ + plugin, + options: { + viewContext: (request) => { + return { + appVersion: pkg.version, + assetPath: '/assets', + config: { + serviceName: 'My Service', + phaseTag: 'beta' + }, + // Add CSRF token if request exists + crumb: request?.plugins.crumb?.generate?.(request) + } + } + } +}) +``` + +The context returned by this function is merged with the plugin's internal context and made available to all templates. + +## model + +The `model` option allows you to provide a pre-built `FormModel` instance to serve a single static form definition. + +When `model` is provided: + +- The plugin serves only that specific form +- No dynamic form loading occurs +- Useful for testing or single-form applications + +When `model` is omitted (recommended for production): + +- Forms are loaded dynamically via `formsService` +- Multiple forms can be served +- Form definitions can be updated without redeploying + +Example (single form): + +```js +import { FormModel } from '@defra/forms-engine-plugin/engine/models/FormModel.js' + +const definition = await getFormDefinition() + +const model = new FormModel( + definition, + { basePath: '/my-form' }, + services +) + +await server.register({ + plugin, + options: { + model, + // ... other options + } +}) +``` + +## Custom globals + +Use the `globals` plugin option to provide custom functions that can be called from within Nunjucks templates. + +Unlike filters which transform values, globals are functions that can be called directly in templates. + +Example: + +```js +await server.register({ + plugin, + options: { + globals: { + getCurrentYear: () => new Date().getFullYear(), + formatCurrency: (amount) => new Intl.NumberFormat('en-GB', { + style: 'currency', + currency: 'GBP' + }).format(amount) + } + } +}) +``` + +In your templates: + +```html +

Copyright {{ getCurrentYear() }}

+

Total: {{ formatCurrency(123.45) }}

+``` + ## Custom filters Use the `filter` plugin option to provide custom template filters.