question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Decide JavaScript and Nunjucks API for passing translation strings

See original GitHub issue

What

We need to decide:

  • what the JavaScript object and keys look like for passing translation strings to component JS
  • what the Nunjucks API keys look like for passing translation strings through to component data attributes
  • what the data attributes look like for translation strings for JS

Example: are keys formatted like show_all_sections, showAllSections? Do they need prefixing with i18n to separate them from other Nunjucks params? What do the data attributes look like, e.g: data-show-all-sections="hello", data-i18n-show-all-sections="hello".

Explore the different options and come to a decision on our preferred option.

Why

We want to implement two ways of passing translation strings to component JS. By designing and agreeing the API for this now, we will make sure that the JS and data-attributes options are consistent with each other, and we’ll be setting conventions for enabling translation of strings in new component JS in future.

Who needs to work on this

Developers

Who needs to review this

Developers

Done when

  • We’ve made a decision on the above
  • We’ve written up our decision on this card (which we can then use when implementing the logic)

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:20 (19 by maintainers)

github_iconTop GitHub Comments

1reaction
querkmachinecommented, Aug 26, 2022

The team seems to be happy with the decisions made here, so I’m going to consider this complete.

To summarise:

  • Configuration objects are not limited to internationalisation support. This is intended to work with future JS configuration work too.
  • Configuration objects will be ‘flattened’ to a single-depth set of key-value pairs to simplify merging.
  • Keys in JS and Nunjucks parameters will use camelCase. HTML data-* attributes will use kebab-case (these are automatically transformed into camelCase when accessed using dataset).
  • Keys in JS and data-* attributes will be namespaced by prefixing them with i18n.. Nunjucks parameters will not, to be consistent with how existing strings are already handled.
  • Nunjucks parameter names will be suffixed with Html. The values passed to these should be manually escaped with the escape/e filter, to account for users who have the global autoescape option turned off.

Examples

Passing a translation through a Nunjucks macro.

{{ govukAccordion({
  showAllSectionsHtml: 'Show everything',
  showSectionHtml: 'Show<span class="govuk-visually-hidden"> this section</span>'
}) }}

How this is interpolated into the template:

<div
  {%- if params.showAllSectionsHtml %} data-i18n.show-all-sections="{{ params.showAllSectionsHtml | escape }}"{% endif %}
  {%- if params.showSectionHtml %} data-i18n.show-section="{{ params.showSectionHtml | escape }}"{% endif %}
>

The equivalent HTML generated by the macro.

<div data-i18n.show-all-sections="Show everything" data-i18n.show-section="Show<span class=&quot;govuk-visually-hidden&quot;> this section</span>">

Passing a translation through the component’s JavaScript initialisation. This supports both nested and flat objects.

new Accordion($element, {
  i18n: {
    showAllSections: 'Show everything',
    showSection: 'Show<span class="govuk-visually-hidden"> this section</span>'
  },
  // OR
  'i18n.showAllSections': 'Show everything',
  'i18n.showSection': 'Show<span class="govuk-visually-hidden"> this section</span>'
}).init()

Passing a translation through Frontend’s initAll function. This will also support nested and flat objects, within each component’s namespace.

window.GOVUKFrontend.initAll({
  accordion: {
    i18n: {
      showAllSections: 'Show everything',
      showSection: 'Show<span class="govuk-visually-hidden"> this section</span>'
    },
    // OR 
    'i18n.showAllSections': 'Show everything',
    'i18n.showSection': 'Show<span class="govuk-visually-hidden"> this section</span>'
  },
})

After the configurations have been merged and flattened, the resulting object should look something like this:

{ 
  'i18n.showAllSections': 'Show everything',
  'i18n.showSection': 'Show<span class="govuk-visually-hidden"> this section</span>'
}
1reaction
querkmachinecommented, Aug 23, 2022

Is that using the escape filter or just relying on autoescape? […] We might want to be explicit about it and use the escape filter? (Although I’m assuming escape doesn’t do anything when autoescape is enabled.)

I was testing in the review app, which has autoescape enabled. Turning it off makes a mess unless the escape filter is used. The filter and config option seem to work identically in terms of what characters they escape.

Do we think we need to provide a Text option that is escaped (somehow?) as well?

It does seem redundant to have both Html and Text versions—one that might be escaped by autoescape, one that will be escaped with the escape filter, both technically able to take HTML—we should probably stick with Html and explicitly escape it, though I don’t feel too strongly on that point.

We should check what happens in older browsers like IE8 / IE9 though which do not use the HTML5 tokenizer.

For what it’s worth, as none of the spikes carried out so far support IE, my means of testing in IE was relatively hacky (read: using console commands to try and extract the data-* attribute value and output it to an innerHTML somewhere). It worked in those instances, but I can’t say I have 100% confidence that it’s without caveats.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Add ability to pass translation strings to accordion component ...
The accordion component has new Nunjucks macro options for passing in translation strings (following the format decided on in Decide JavaScript and Nunjucks...
Read more >
nunjucks templating docs
This variable can contain a string that points to a template file, ... If you have passed a javascript method to your template,...
Read more >
How to safely render JSON into an inline <script> using ...
We're rendering this from a Nunjucks template, and passing the JSON object as a value data in the context. This can contain arbitrary...
Read more >
Deploy a basic "Google Translate" Express.js app on App ...
You will learn how to use the Google Cloud Translation API in a simple web application. This app can be run locally or...
Read more >
Four Killer Features of Nunjucks | CSS-Tricks
Nunjucks calls itself “A rich and powerful templating language for JavaScript”, which sounds about right. It's not intentionally super ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found