From 925f290b86e546b2aabcc6f953618b2ab0f7ba36 Mon Sep 17 00:00:00 2001 From: Rhodine-orleans-lindsay Date: Sat, 28 Mar 2026 04:07:07 +0000 Subject: [PATCH] HOFF-2043: Nunjucks Refactoring (Details summary partial) - create detailsComponent macro that reads ${route}.details.summary and ${route}.details.text from pages.json but can also be customised by passing additional arguments for custom summary and text - update readme with documentation on details component usage --- README.md | 47 +++++++++++++++++++ controller/controller.js | 17 +++++++ .../views/partials/details-summary.html | 19 ++++---- .../sandbox/views/form-guidance-link.html | 2 +- 4 files changed, 76 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 67ecfa61..166ac153 100644 --- a/README.md +++ b/README.md @@ -1826,6 +1826,53 @@ app.set("views", [ The views are now available when calling `res.render('view-name')` from express. +#### Details Component + The `detailsComponent` macro can be used to display a details summary and text on a page. It can take three parameters: + + `details`: An object containing the summary and text to display. The summary is required, but the text is optional. + + `customSummary`: A string that can be used to override the summary in the details object. + + `customText`: A string that can be used to override the text in the details object. + + This allows the component to be reused multiple times on the same page with different text. + + If `customSummary` or `customText` are not provided, the macro will use the values from the details object. If the details object does not contain a summary or text, it will default to an empty string. + + + + **Example usage:** + + Use default summary and text from details object set in `pages.${route}.details`: +``` +{ + "test-page": { + "details":{ + "summary": Details Summary", + "text": "Details Text", + "custom-summary": "Custom Summary", + "custom-text": "Custom Text + } + } +} +``` +In your view file: +``` +{% from "partials/details-summary.html" import detailsComponent %} + +{# Default details component #} +{{ detailsComponent(details) }} + +{# Set Override arguments - optional #} +{% set overrideSummary = t('pages.test-page.details.custom-summary') %} {# This can also be an ordinary string #} +{% set overrideText = t('pages.test-page.details.custom-text') %} {# This can also be an ordinary string #} + +{# Override just default summary #} +{{ detailsComponent(details, overrideSummary) }} + +{# Override both defaultsummary and text #} +{{ detailsComponent(details, overrideSummary, overrideText) }} +``` #### HOF Application When used in a hof application in conjunction with [express-partial-templates](https://github.com/UKHomeOffice/express-partial-templates) the contents of the views directory are added to `res.locals.partials`. These are added right to left so conflicting views are resolved from the left-most directory. diff --git a/controller/controller.js b/controller/controller.js index 3c0f3c02..7af42b5f 100644 --- a/controller/controller.js +++ b/controller/controller.js @@ -127,6 +127,7 @@ module.exports = class Controller extends BaseController { serviceName: this.getServiceName(lookup, res.locals), captionHeading: this.getCaptionHeading(route, lookup, res.locals), warning: this.getWarning(route, lookup, res.locals), + details: this.getDetails(route, lookup, res.locals), subHeading: this.getSubHeading(route, lookup, res.locals), intro: this.getIntro(route, lookup, res.locals), backLink: this.getBackLink(req, res), @@ -170,6 +171,22 @@ module.exports = class Controller extends BaseController { return lookup(`pages.${route}.warning`, locals); } + getDetails(route, lookup, locals) { + const details = lookup(`pages.${route}.details`, locals); + if (details && typeof details === 'object') { + return details; + } + const summary = lookup(`pages.${route}.details.summary`, locals); + const text = lookup(`pages.${route}.details.text`, locals); + if (summary || text) { + return { + summary, + text + }; + } + return details; + } + getTitle(route, lookup, fields, locals) { let fieldName = ''; if (_.size(fields)) { diff --git a/frontend/template-partials/views/partials/details-summary.html b/frontend/template-partials/views/partials/details-summary.html index bfadd229..0523cc4d 100644 --- a/frontend/template-partials/views/partials/details-summary.html +++ b/frontend/template-partials/views/partials/details-summary.html @@ -1,8 +1,11 @@ -
- - {{summary}} - -
- {{details}} -
-
+{% from "govuk/components/details/macro.njk" import govukDetails %} + +{% macro detailsComponent(details, customSummary=null, customText=null) %} + {% set summaryText = customSummary or details.summary or '' %} + {% set text = customText or details.text or '' %} + + {{ govukDetails({ + summaryText: summaryText, + text: text + }) }} +{% endmacro %} diff --git a/sandbox/apps/sandbox/views/form-guidance-link.html b/sandbox/apps/sandbox/views/form-guidance-link.html index c05cbbb6..df9a473c 100644 --- a/sandbox/apps/sandbox/views/form-guidance-link.html +++ b/sandbox/apps/sandbox/views/form-guidance-link.html @@ -2,5 +2,5 @@ {% block page_content %}

{{ t('pages.build-your-own-form.subheader') }}

- Link to HOF form guidance + Link to HOF form guidance {% endblock %}