Difference between revisions of "JSON Resource Bundles"
(→Objects) |
(→Typical with Keys for Comments) |
||
(34 intermediate revisions by 4 users not shown) | |||
Line 4: | Line 4: | ||
JSON files are increasingly used with JavaScript as a means to capture strings to be translated. |
JSON files are increasingly used with JavaScript as a means to capture strings to be translated. |
||
+ | == Example of LRM Supported JSON Files == |
||
− | == JSON File Naming == |
||
+ | |||
− | In order to detect and import changes, LRM 2.1 requires JSON files to also adhere to the following standards. |
||
+ | === Typical === |
||
− | The json files must follow this naming convention: '''filename_<locale>.json''' or '''filename_<locale>_<country>.json'''. For example, |
||
+ | This file, named for instance ''errors_en.json'', looks similar to a .properties file, with a key/value pair on each line. This is the most common and simple file to handle: |
||
+ | <pre> |
||
+ | { |
||
+ | "title": "Woops!", |
||
+ | "message": "Something went wrong. Try again later." |
||
+ | } |
||
+ | </pre> |
||
+ | |||
+ | === Typical with Keys for Comments=== |
||
+ | This file, named for instance ''resources_en.json'', looks similar to a .properties file, with a key/value pair on each line. The first line has a '''key which start with an underscore''', indicating a description for the key just after it. The text for "_description_groupAccessOpen" will not be translated: |
||
+ | <pre> |
||
+ | { |
||
+ | "_description_groupAccessOpen", "To help users with the Open in the top window", |
||
+ | "groupAccessOpen": "Open", |
||
+ | "groupAccessInvitationOnly": "Invitation Only", |
||
+ | "groupAccessRequestToJoin": "Request To Join", |
||
+ | "all_volunteers" : "All Volunteers" |
||
+ | } |
||
+ | </pre> |
||
+ | |||
+ | === Objects === |
||
+ | The keys must be unique within a file. Sometimes, objects allow for an organization within the files which matches the developers' code. |
||
+ | <pre> |
||
+ | { |
||
+ | "the_cat": "The Cat", |
||
+ | "dogs": { |
||
+ | "pitbull": "A pitbull", |
||
+ | "collie": "A collie", |
||
+ | "small_dogs": { |
||
+ | "poodle": "A teacup poodle" |
||
+ | } |
||
+ | } |
||
+ | } |
||
+ | </pre> |
||
+ | |||
+ | |||
+ | == JSON File Structure == |
||
+ | |||
+ | As with all resource files, LRM requires JSON files to adhere to specific standards in naming and directory structure in order to detect and import changes. |
||
+ | |||
+ | The locale of the target files must be made explicit through either a pattern of file names or a pattern of directory names. Please use the same pattern consistently - as only one pattern is supported per file extension per project. |
||
+ | |||
+ | This is described in depth at [[On_Boarding_an_LRM_Project#Build]] |
||
+ | |||
+ | A few examples for reference: |
||
+ | |||
+ | === Locale Defined in File Name === |
||
*'''resources_en.json''' or resources_en_US.json, |
*'''resources_en.json''' or resources_en_US.json, |
||
− | * |
+ | *'''resources_fr.json''' or resources_fr_FR.json, etc. |
+ | With multiple directories such as: |
||
− | We strongly recommend file names should be unique, even if they are in different directories. LRM sends unique file names per prep kits. For example, if you have two JSON files under locales/ and under module1/locales, you could name them: |
||
* locales/common_resources_en.json |
* locales/common_resources_en.json |
||
* modules1/locales/module1_messages_en.json |
* modules1/locales/module1_messages_en.json |
||
+ | |||
+ | === Locale Defined in Directory Name === |
||
+ | *'''en/resources.json''', '''fr_FR/resources.json''', '''zh_TW_HANS/resources.json''', |
||
+ | OR |
||
+ | *'''modulename_en/resources.json''', '''modulename_fr_FR/resources.json''', '''modulename_zh_TW_HANS/resources.json''' |
||
+ | |||
+ | Multiple directories are supported. For example: |
||
+ | * locales/common_resources/en/resources.json |
||
+ | * locales/common_resources/fr_FR/resources.json |
||
+ | * locales/common_resources/zh_TW_HANS/resources.json |
||
+ | * modules1/locales/en/resources.json |
||
+ | * modules1/locales/fr_FR/resources.json |
||
+ | * modules1/locales/zh_TW_HANS/resources.json |
||
+ | |||
+ | For full details, please refer to [[On_Boarding_an_LRM_Project#Build]] |
||
== JSON File Format == |
== JSON File Format == |
||
JSON files are like XML files: They can have complex schemas to represent complex objects. For translation purposes, LRM supports a restricted subset of the overall JSON format. |
JSON files are like XML files: They can have complex schemas to represent complex objects. For translation purposes, LRM supports a restricted subset of the overall JSON format. |
||
+ | ===Resource files must start with an object=== |
||
+ | Resource files cannot start with an array (square bracket). Each resource file must start and end with a curly bracket. |
||
− | ===Arrays are |
+ | ===Arrays are supported=== |
+ | Each item in the array must be on its own line. If a change occurs within the array, then the entire array is set out for translation. Nested arrays are allowed. |
||
− | String references in the code, from an i18n point of view, is unmanageable for JSON arrays. In addition, many L10n vendors do not support JSON arrays. (Sample JSON files are located in LRM-Server-2.1/''samples/JSON_Examples'') |
||
+ | <pre> |
||
+ | { |
||
+ | "array1" : [ |
||
+ | |||
+ | "item1", |
||
+ | |||
+ | "item2", |
||
+ | |||
+ | [ "item1InArray", |
||
+ | |||
+ | "item2InArray" |
||
+ | |||
+ | ], |
||
+ | |||
+ | "item3" |
||
+ | |||
+ | ] |
||
+ | } |
||
+ | </pre> |
||
===There is only one key/value per line.=== |
===There is only one key/value per line.=== |
||
Line 59: | Line 142: | ||
"key1": true |
"key1": true |
||
</pre> |
</pre> |
||
+ | === Keys must be unique=== |
||
− | |||
+ | In order to prevent a duplicate key error all keys must be unique. |
||
− | == Example of LRM Supported JSON Files == |
||
+ | * Valid |
||
− | |||
− | === Typical === |
||
− | This file, named for instance ''errors_en.json'', looks similar to a .properties file, with a key/value pair on each line. This is the most common and simple file to handle: |
||
<pre> |
<pre> |
||
+ | "key1":"0", |
||
− | { |
||
− | " |
+ | "key1_1" : { |
+ | "one":"one" |
||
− | "message": "Something went wrong. Try again later." |
||
+ | } |
||
− | } |
||
</pre> |
</pre> |
||
+ | * Invalid |
||
− | === Typical with Keys for Comments=== |
||
− | This file, named for instance ''resources_en.json'', looks similar to a .properties file, with a key/value pair on each line. The first line has a key which start with an underscore, indicating a description for the key just after it. The text for "_description_groupAccessOpen" will not be translated: |
||
<pre> |
<pre> |
||
+ | "key1":"0", |
||
− | { |
||
+ | "key1": { |
||
− | "_description_groupAccessOpen", "To help users with the Open in the top window", |
||
− | " |
+ | "one":"one" |
+ | } |
||
− | "groupAccessInvitationOnly": "Invitation Only", |
||
− | "groupAccessRequestToJoin": "Request To Join", |
||
− | "all_volunteers" : "All Volunteers" |
||
− | } |
||
</pre> |
</pre> |
||
− | === |
+ | === Language Tags === |
+ | |||
− | The keys must be unique within a file. Sometimes, objects allow for an organization within the files which matches the developers' code. |
||
+ | A language tag is the language code of the resource file's locale and located at the top of the file. When a Localzyer prep kit file is imported, the language tag will reflect the locale of the imported file. |
||
− | <pre> |
||
+ | |||
− | { |
||
− | + | { |
|
− | + | "en": { |
|
− | + | "nestedKey": { |
|
− | + | "login": "Log In", |
|
− | + | "logout": "Log Out", |
|
− | + | "name": "Name" |
|
− | + | } |
|
− | + | } |
|
+ | } |
||
− | "Admin": "Administrator", |
||
+ | |||
− | "Manager": "Manager" |
||
+ | ''' The pattern of the language tag is configurable ''' |
||
− | }, |
||
+ | |||
− | }, |
||
+ | In the above example, 'en' is a language-only language tag. This is the default pattern. The language tag pattern is configurable through the [[Group_Configuration_Files#config_lrm_info.properties|config_lrm_info.properties]] file. The language tag pattern must match the pattern that are in your resource files. However, your resource files must contain consistent patterns or 'MISSING_KEY' errors may occur. |
||
− | "all_volunteers" : "All Volunteers" |
||
+ | |||
− | } |
||
+ | |||
− | </pre> |
||
+ | ''' Localyzer ignores the JSON language tag when determining the resource keys ''' |
||
+ | |||
+ | If a JSON file contains nested keys, then Localyzer ''flattens out'' the structure so that a unique key can be created. Each field name within the nested object has a separator of '''''_^o^_'''''. The language tag is not included in the creation of the unique key. The following is an example of the unique LRM resource keys created from the above JSON file. |
||
+ | |||
+ | Example of the key/value pairs created by Localyzer for the above file: |
||
+ | |||
+ | {| class="wikitable" style="border: none; background: none;" |
||
+ | | rowspan="4" style="border: none; background: none;"| |
||
+ | ! scope="col" | Key |
||
+ | ! scope="col" | Value |
||
+ | |- |
||
+ | | nestedkey_^o^_login || Log In |
||
+ | |- |
||
+ | | nestedkey_^o^_logout || Log Out |
||
+ | |- |
||
+ | | nestedkey_^o^_name || Name |
||
+ | |- |
||
+ | |} |
||
+ | |||
+ | === Global Tags === |
||
+ | A global tag is a static top-level key that is in all files but should be ignored by Localyzer when determining keys to be sent out for translation. |
||
+ | Example: |
||
+ | |||
+ | { |
||
+ | "ProjectLogin": { |
||
+ | "nestedKey": { |
||
+ | "login": "Log In", |
||
+ | "logout": "Log Out", |
||
+ | "name": "Name" |
||
+ | } |
||
+ | } |
||
+ | } |
||
+ | |||
+ | ''' Global tags are configurable ''' |
||
+ | |||
+ | In the above example, 'ProjectLogin' is a global tag and needs to be added to the ''global.tags'' attribute of the [[Group_Configuration_Files#config_lrm_info.properties|config_lrm_info.properties]] file. There can be multiple global tags as long as they are at the top of file. In the above example, both ''ProjectLogin'' and ''nestedKey'' could be global tags. Global tags are expected to be in all files...both base and target. |
Latest revision as of 18:38, 15 April 2024
Contents
- 1 JSON Resource Bundles
- 2 Example of LRM Supported JSON Files
- 3 JSON File Structure
- 4 JSON File Format
- 4.1 Resource files must start with an object
- 4.2 Arrays are supported
- 4.3 There is only one key/value per line.
- 4.4 End-object character (curly bracket) may not exist on the same line as a key/value
- 4.5 Values associated with a key must be a string
- 4.6 Keys must be unique
- 4.7 Language Tags
- 4.8 Global Tags
JSON Resource Bundles
Well-formed JSON is required and specified by http://www.ietf.org/rfc/rfc4627.txt. JSON can in effect have any 'schema' and only some subset of JSON makes sense for Localization. JSON resource bundles are supported starting with LRM 2.1. The details of the LRM supported format is provided below.
JSON files are increasingly used with JavaScript as a means to capture strings to be translated.
Example of LRM Supported JSON Files
Typical
This file, named for instance errors_en.json, looks similar to a .properties file, with a key/value pair on each line. This is the most common and simple file to handle:
{ "title": "Woops!", "message": "Something went wrong. Try again later." }
Typical with Keys for Comments
This file, named for instance resources_en.json, looks similar to a .properties file, with a key/value pair on each line. The first line has a key which start with an underscore, indicating a description for the key just after it. The text for "_description_groupAccessOpen" will not be translated:
{ "_description_groupAccessOpen", "To help users with the Open in the top window", "groupAccessOpen": "Open", "groupAccessInvitationOnly": "Invitation Only", "groupAccessRequestToJoin": "Request To Join", "all_volunteers" : "All Volunteers" }
Objects
The keys must be unique within a file. Sometimes, objects allow for an organization within the files which matches the developers' code.
{ "the_cat": "The Cat", "dogs": { "pitbull": "A pitbull", "collie": "A collie", "small_dogs": { "poodle": "A teacup poodle" } } }
JSON File Structure
As with all resource files, LRM requires JSON files to adhere to specific standards in naming and directory structure in order to detect and import changes.
The locale of the target files must be made explicit through either a pattern of file names or a pattern of directory names. Please use the same pattern consistently - as only one pattern is supported per file extension per project.
This is described in depth at On_Boarding_an_LRM_Project#Build
A few examples for reference:
Locale Defined in File Name
- resources_en.json or resources_en_US.json,
- resources_fr.json or resources_fr_FR.json, etc.
With multiple directories such as:
- locales/common_resources_en.json
- modules1/locales/module1_messages_en.json
Locale Defined in Directory Name
- en/resources.json, fr_FR/resources.json, zh_TW_HANS/resources.json,
OR
- modulename_en/resources.json, modulename_fr_FR/resources.json, modulename_zh_TW_HANS/resources.json
Multiple directories are supported. For example:
- locales/common_resources/en/resources.json
- locales/common_resources/fr_FR/resources.json
- locales/common_resources/zh_TW_HANS/resources.json
- modules1/locales/en/resources.json
- modules1/locales/fr_FR/resources.json
- modules1/locales/zh_TW_HANS/resources.json
For full details, please refer to On_Boarding_an_LRM_Project#Build
JSON File Format
JSON files are like XML files: They can have complex schemas to represent complex objects. For translation purposes, LRM supports a restricted subset of the overall JSON format.
Resource files must start with an object
Resource files cannot start with an array (square bracket). Each resource file must start and end with a curly bracket.
Arrays are supported
Each item in the array must be on its own line. If a change occurs within the array, then the entire array is set out for translation. Nested arrays are allowed.
{ "array1" : [ "item1", "item2", [ "item1InArray", "item2InArray" ], "item3" ] }
There is only one key/value per line.
- Valid
"key1":"This is my value for key1", "key2":"This is my value for key2"
- Invalid
"key1":"This is my value for key1","key2":"This is my value for key2"
End-object character (curly bracket) may not exist on the same line as a key/value
- Valid
"keys": { "key1":"This is my value for key1" }
- Invalid
"keys": { "key1":"This is my value for key1"}
Values associated with a key must be a string
Numeric and boolean values are not allowed.
- Valid
"key1":"0"
- Invalid
"key1":0, "key1": true
Keys must be unique
In order to prevent a duplicate key error all keys must be unique.
- Valid
"key1":"0", "key1_1" : { "one":"one" }
- Invalid
"key1":"0", "key1": { "one":"one" }
Language Tags
A language tag is the language code of the resource file's locale and located at the top of the file. When a Localzyer prep kit file is imported, the language tag will reflect the locale of the imported file.
{ "en": { "nestedKey": { "login": "Log In", "logout": "Log Out", "name": "Name" } } }
The pattern of the language tag is configurable
In the above example, 'en' is a language-only language tag. This is the default pattern. The language tag pattern is configurable through the config_lrm_info.properties file. The language tag pattern must match the pattern that are in your resource files. However, your resource files must contain consistent patterns or 'MISSING_KEY' errors may occur.
Localyzer ignores the JSON language tag when determining the resource keys
If a JSON file contains nested keys, then Localyzer flattens out the structure so that a unique key can be created. Each field name within the nested object has a separator of _^o^_. The language tag is not included in the creation of the unique key. The following is an example of the unique LRM resource keys created from the above JSON file.
Example of the key/value pairs created by Localyzer for the above file:
Key | Value | |
---|---|---|
nestedkey_^o^_login | Log In | |
nestedkey_^o^_logout | Log Out | |
nestedkey_^o^_name | Name |
Global Tags
A global tag is a static top-level key that is in all files but should be ignored by Localyzer when determining keys to be sent out for translation. Example:
{ "ProjectLogin": { "nestedKey": { "login": "Log In", "logout": "Log Out", "name": "Name" } } }
Global tags are configurable
In the above example, 'ProjectLogin' is a global tag and needs to be added to the global.tags attribute of the config_lrm_info.properties file. There can be multiple global tags as long as they are at the top of file. In the above example, both ProjectLogin and nestedKey could be global tags. Global tags are expected to be in all files...both base and target.