Skip to content

Commit

Permalink
Support markdown for payment link details
Browse files Browse the repository at this point in the history
  • Loading branch information
stephencdaly committed Oct 2, 2024
1 parent 35224b6 commit 1fc08b2
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 1 deletion.
2 changes: 1 addition & 1 deletion app/payment-links/start/start.njk
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<h1 class="govuk-heading-l">{{ product.name }}</h1>

{% if product.description %}
<p class="govuk-body" data-cy="product-description">{{ product.description | striptags(true) | escape | nl2br }}</p>
<div data-cy="product-description">{{ product.description | striptags(true) | formatMarkdown | safe }}</div>
{% endif %}

{{ govukButton({
Expand Down
68 changes: 68 additions & 0 deletions app/utils/format-markdown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* Credit: https://github.com/ministryofjustice/opg-performance-data/blob/63fac0c26a701f37cfa2d4d8229cf82937ad5047/markdown-it-gds.js#L4
*/

'use strict'

const markdownIt = require('markdown-it')

const linkExternalStack = []

/**
* Rules that can be enabled/disabled for markdown-it can be found here:
* https://github.com/markdown-it/markdown-it/blob/0fe7ccb4b7f30236fb05f623be6924961d296d3d/lib/parser_block.mjs
* https://github.com/markdown-it/markdown-it/blob/HEAD/lib/parser_inline.mjs
*/
const md = markdownIt({
html: false,
breaks: true
})
.disable(['heading', 'lheading', 'image', 'table', 'code', 'fence', 'blockquote', 'hr', 'html_block', 'reference', 'emphasis', 'backticks', 'strikethrough', 'html_inline', 'autolink', 'entity'])

function defaultRender (tokens, idx, options, env, self) {
return self.renderToken(tokens, idx, options);
}

md.renderer.rules.paragraph_open = function (tokens, idx, options, env, self) {
tokens[idx].attrPush(["class", "govuk-body"]);
return defaultRender(tokens, idx, options, env, self);
}

md.renderer.rules.link_open = function (tokens, idx, options, env, self) {
let externalLink = false;
tokens[idx].attrPush(["class", "govuk-link"]);
if (tokens[idx].attrGet("href").indexOf("http") === 0) {
externalLink = true;
tokens[idx].attrPush(["target", "_blank"]);
tokens[idx].attrPush(["rel", "noreferrer noopener"]);

linkExternalStack.push(externalLink);
}
return defaultRender(tokens, idx, options, env, self);
}

md.renderer.rules.link_close = function (tokens, idx, options, env, self) {
const externalLink = linkExternalStack.pop();
if (externalLink) {
return `<span class="govuk-visually-hidden">(opens in new tab)</span></a>`;
}
return defaultRender(tokens, idx, options, env, self);
};

md.renderer.rules.bullet_list_open = function (tokens, idx, options, env, self) {
tokens[idx].attrPush(["class", "govuk-list govuk-list--bullet"]);
return defaultRender(tokens, idx, options, env, self);
}

md.renderer.rules.ordered_list_open = function (tokens, idx, options, env, self) {
tokens[idx].attrPush(["class", "govuk-list govuk-list--number"]);
return defaultRender(tokens, idx, options, env, self);
}

function formatMarkdown (rawText) {
return md.render(rawText)
}

module.exports = {
formatMarkdown
}
4 changes: 4 additions & 0 deletions config/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const loggingMiddleware = require('../app/middleware/logging-middleware')
const { requestContextMiddleware } = require('../app/clients/base/request-context')
const Sentry = require('../app/utils/sentry.js').initialiseSentry()
const replaceParamsInPath = require('../app/utils/replace-params-in-path')
const { formatMarkdown } = require('../app/utils/format-markdown')

// Global constants
const JAVASCRIPT_PATH = staticify.getVersionedPath('/js/application.min.js')
Expand Down Expand Up @@ -106,6 +107,9 @@ function initialiseTemplateEngine (app) {
// if it's not production we want to re-evaluate the assets on each file change
nunjucksEnvironment.addGlobal('css_path', staticify.getVersionedPath('/stylesheets/application.min.css'))
nunjucksEnvironment.addGlobal('js_path', NODE_ENV === 'production' ? JAVASCRIPT_PATH : staticify.getVersionedPath('/js/application.js'))

// Load custom Nunjucks filters
nunjucksEnvironment.addFilter('formatMarkdown', formatMarkdown)
}

function initialisePublic (app) {
Expand Down

0 comments on commit 1fc08b2

Please sign in to comment.