Flatten i18n message keys in message JSON #4979
Labels
💻 aspect: code
Concerns the software code in the repository
🧰 goal: internal improvement
Improvement that benefits maintainers, not users
help wanted
Open to participation from the community
🟩 priority: low
Low priority and doesn't need to be rushed
🧱 stack: frontend
Related to the Nuxt frontend
🟨 tech: javascript
Involves JavaScript
Problem
Our current vue/i18n messages files utilise nested JSON objects to discriminate keys. A sample from our
en.json5
looks like this:Code that references these keys does so in a dot-delimited path format. For example,
hero.disclaimer.content
references the key at that path in the nested object.While nested objects may provide a slight advantage to authorship of the messages file, it presents a severe disadvantage when trying to find the message from a key in the code referencing it. Using the example above, if you wanted to see the message associated with the key
hero.disclaimer.content
, and tried to search the codebase for that literal string, you would not find it. Instead, you would have to know to navigate to theen.json5
, and then find thehero
key, find itsdisclaimer
key, and then finally thecontent
key. Sometimes you can shortcut this by searching for just the final part of the key, in this casecontent
. However, we have 31 keys that end with the segment.content
, so searchingcontent:
in the file would still require looking through individual instances to find it. The example above also uses relatively small and shallow nesting and does not illustrate the additional difficulty of navigating deeply nested keys in large collections of messages, likesensitive.designations.userReported.title.description.a
.Description
Instead, I propose we "flatten" the messages objects where the keys are the full path to the message. In other words, remove all nesting.
For example, the messages excerpt above would turn into this, instead:
This format is backwards compatible with our existing messages objects. If you replace the 404 and hero objects with the flattened version above and run your local frontend, there is zero issue.
The benefit of this approach is that it is easily searchable in both directions. From the messages file, it is easier to find uses of the keys. From runtime code, it is easier to find the content of the translation string. Additionally, our
json-to-pot
script could be simplified, as right now it has to collapse keys when converting to POT, becausePOT
is a flat-format.Our POT-to-JSON conversion re-explodes the keys into the nested object. We should retain this behaviour in the final output messages files. A meaningful downside to the flat format is an increase in the total character size of the keys, due to the repeated strings.
The nested example minifies to 509 characters (expand for minified version).
The flattened example minifies to 527 characters (expand for minified version).
Because this change is proposed to improve authorship (not transport or anything else relevant to the final generated files), and because it is backwards compatible with the nested format, we should retain the nested format for the produced JSON files.
To implement this change, we will need to flatten the
en.json5
's keys. This can be done by hand, or using something like this online JSON flattening tool, except that tool and others like it strip comments and make other unwanted transformations, so would still require manual changes to address those... Becausejson-to-pot
already has to flatten the keys for use in the POT files, it shouldn't be too hard to adapt our existingjson-to-pot
script into ajson-to-flattened-json
script that preserves comments, single-quoted strings (which we use to avoid needing to escape double quotes in some strings), etc. I would recommend that approach, it seems like the least tedious option to me!The text was updated successfully, but these errors were encountered: