1EdTech Localization Framework
Spec Version 1.0
| Document Version: | 0.1 |
| Date Issued: | November 6, 2022 |
| Status: | This document is for review and comment by 1EdTech Contributing Members. |
| This version: | https://www.imsglobal.org/spec/l12n/v1p0/ |
| Latest version: | https://www.imsglobal.org/spec/l12n/latest/ |
| Errata: | https://www.imsglobal.org/spec/l12n/v1p0/errata/ |
IPR and Distribution Notice
Recipients of this document are requested to submit, with their comments, notification of any relevant patent claims or other intellectual property rights of which they may be aware that might be infringed by any implementation of the specification set forth in this document, and to provide supporting documentation.
1EdTech takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on 1EdTech's procedures with respect to rights in 1EdTech specifications can be found at the 1EdTech Intellectual Property Rights webpage: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf .
Use of this specification to develop products or services is governed by the license with 1EdTech found on the 1EdTech website: http://www.imsglobal.org/speclicense.html.
Permission is granted to all parties to use excerpts from this document as needed in producing requests for proposals.
The limited permissions granted above are perpetual and will not be revoked by 1EdTech or its successors or assigns.
THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTER'S OWN RISK, AND NEITHER THE CONSORTIUM, NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION.
Public contributions, comments and questions can be posted here: http://www.imsglobal.org/forums/ims-glc-public-forums-and-resources .
© 2022 1EdTech™ Consortium, Inc. All Rights Reserved.
Trademark information: http://www.imsglobal.org/copyright.html
Abstract
This document defines a set of modules that are intended to enable the enhancement of localization capabilities of 1EdTech specifications.
1. Introduction
This document defines a set of modules that are intended to enable the enhancement of localization capabilities of 1EdTech specifications. @@@TODO
1.1 Status of this document
This is a pre-base document working draft made available for initial review.
1.2 Document Set
@@@TODO
2. Conformance
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY, MUST, MUST NOT, OPTIONAL, RECOMMENDED, REQUIRED, SHALL, SHALL NOT, SHOULD, and SHOULD NOT in this document are to be interpreted as described in [RFC2119].
An implementation of this specification that fails to implement a MUST/REQUIRED/SHALL requirement or fails to abide by a MUST NOT/SHALL NOT prohibition is considered nonconformant. SHOULD/SHOULD NOT/RECOMMENDED statements constitute a best practice. Ignoring a best practice does not violate conformance but a decision to disregard such guidance should be carefully considered. MAY/OPTIONAL statements indicate that implementers are entirely free to choose whether or not to implement the option.
3. Multilinguality Support Module
The Multilinguality Support module defines a mechanism to provide translation information for unilingual documents using a decorator pattern. This allows for adorning of nodes in existing data models with translation information, without needing to modify the existing data model schema/structure.
3.1 Rationale
Documents and data payloads defined by 1EdTech specifications are typically unilingual in nature, meaning that the information is provided in a single language.
As educational applications are serving information to users in multilingual contexts, the need for supporting controlled multilingual information provisioning is crucial. For example, an institution may wish to ensure that the information broadcasted from a Student Information System (SIS) to multiple clients is uniformly translated into multiple languages by using a single canonical source for the translation information, rather than leaving it up to each client application to provide the translation themselves.
Traditionally, API features such as HTTP Language Negotation [RFC3282] have been implicitly or explicitly referred to as the methodology to employ when needing to enable multilingual support in data transactions.
However, a number of use cases have emerged that warrant the definition of an alternative approach to HTTP Language Negotation for enablement of multilingual support. One primary area where these use cases occur is with asynchronous (pub/sub) protocols, where providers and consumers are decoupled such that content negotiation simply can not occur.
3.2 Design Goals
The design goals for the multilinguality support module defined in this document are:
- Protocol agnosticism
- Support for multilinguality should be protocol agnostic, i.e. not dependent on e.g. the REST or other protocol features.
- Non-obtrusive for unilingual implementations
- Support for multilinguality should be designed such that it does not increase complexity for implementations that do not use multilinguality features.
- Specificity categorization
- Some translation information applies only to a single unique document instance, and other information can apply equally to a set of documents. It should be possible to indicate this nature of a translation unit to the consumer.
- Translation of extensions
- In addition to being able to address core data model fields with translation information, extension space information should also be translatable.
- Translation of both keys and values
- The provided translation information should be able to target both keys and values in a data model. For example, in the information unit "role equals teacher", both the "role" and "teacher" terms are translatable.
- Caching and refresh triggers
- Consumers of translation information should be able to cache translation information for fields/values that reoccur beyond a single document instance. Providers of translation information should be able to signal when translation information for reoccuring fields/values have changed (i.e. indicate that the cache should be repopulated).
Some bindings provide native support for multilinguality (cf. e.g. String Internatonalization in [json-ld11]). In the instance where specifications being developed use such bindings, working groups may elect to use the native feature insted of the mechanism defined here.
3.3 Overview
3.3.1 Localized Strings
The atomic unit of the Multilinguality Support module is the LocalizedString class, which is a tuple consisting of a language code and a string value. Any number of LocalizedString instances can be associated with a unilingual target node, thus making the target node multilingual.
{
"language": "luy-KE",
"value": "...string..."
}3.3.2 Targeting Nodes
Association of LocalizedString instances to nodes in the target instance document is done by using selector expressions, similar to e.g. CSS. This means that the LocalizedString instances need not be located in direct adjacency to the node being decorated with translation information (which allows us to meet the non-obtrusiveness design goal).
The LocalizationItem class is used to couple a selector expression with a set of LocalizedString instances. The intended result is that each node in the target instance document that matches the selector expression becomes decorated with the given set of LocalizedString instances.
{
"select": "...selector expression... ",
"apply": [
{
"language": "ar-ER",
"value": "...string..."
},
{
"language": "yue",
"value": "...string..."
}
]
}
The actual syntax of the selector expression varies depending on which binding is being used. For an XML binding, this module stipulates that XPath [xpath-30] be the choice, and for a JSON binding JsonPath [JSONPATH]. Each specification that uses this module MUST normatively define the concrete syntax, and may override the above stipulations.
To retain consistency in the target instance document, the grammar used for the document type MUST provide facilities to define which language is the default (root) language of the document. The 1EdTech Common Data Model [CDM] defines properties to use for this purpose.
3.3.3 Applying the decoration
Given that the default (root) language of the document is specified in a document instance, we can illustrate the effect of the multilinguality decoration process like this: prior to the decoration phase, the document instance is unilingual (in this case using English as the root language), and a single target node (key-value) pair would, using a JSON binding, have the following form:
role: "teacher" //implicit language "en" inherited from document root language
The decoration process adds two translations (swedish and french) to the node using a LocalizationItem with the following structure (in this example using a JSON binding and JSONPath syntax for the selector):
{
select: "$.role",
apply: [
{
language:"sv",
value:"lärare",
},{
language:"fr",
value:"professeur",
}
]
}
After the decoration has been applied, the target node can be said to logically have been transformed to this state (however please note that the post-decoration data representation is an implementation-specific runtime concern and not dictated by this specification):
role: [
{value: "teacher", language: "en"},
{value: "lärare", language: "sv"},
{value: "professeur" language: "fr"}
]
3.3.4 Aggregation
Instance documents typically contain multiple nodes that can be targets for a multilingual decoration. The LocalizationData class serves as the container for all LocalizationItem objects that apply to a given instance document.
The LocalizationItems inside a LocalizationData object are divided into two top-level categories that specify the scope of the contained LocalizationItems:
- global
- LocalizationItems that apply to all document instances that adher to the same grammar/document type.
Global LocalizationItems change rarely. Implementations MAY cache global items and reuse them in
multiple/subsequent document instances that adher to the same grammar/document type. Implementations that
perform caching MUST heed the
dateLastModifiedtimestamp associated with the contained collections and reset the cache if the given time is newer than the time the cache was last populated. - local
- LocalizationItems specific to values of nodes in this document instance. Implementations MUST NOT reuse these items in multiple/subsequent document instances.
The LocalizationItems inside the global scope category are further divided into two
subcategories:
- names
- The contained LocalizationItems should be applied to node names (i.e. the key in a
key-value pair).
LocalizationItems for names change rarely. Implementations MAY cache these items and reuse them in
multiple/subsequent
document instances that adher to the same grammar/document type. Implementations that perform caching MUST
heed the
dateLastModifiedtimestamp associated with the collection and reset the cache if the given time is newer than the time the cache was last populated. - values
- The contained LocalizationItems should be applied to node values (i.e. the value in a key-value pair)
The LocalizationData object thus has the following overall structure:
{
global: { //items in global scope
names: {
dateLastModified: 2022-11-07T01:02:03+02:00, //cache-refresh indicator
items: [LocalizationItem] //global items that apply to node names (keys)
}
values: {
dateLastModified: 2022-11-07T01:02:03+02:00, //cache-refresh indicator
items: [LocalizationItem] //items that apply to node values (keys)
},
local: { //items in local scope, no cache indicator
items: [LocalizationItem] //items that apply to node values (keys)
}
}
}
For a LocalizationData object to be valid, at least one of the local, global.values
or global.names nodes MUST be present.
3.3.5 Association
There are two ways to associate a LocalizationData object with a document instance:
- By inclusion
- The LocalizationData object is included directly in the document instance using the
localizationDataproperty. - By reference
- The LocalizationData object is referenced at a remote location using
localizationDataUrlproperty.Issue 2TODO security model for localizationDataUrl
Any given document instance may contain neither, one or both of the localizationData and
localizationDataUrl properties. If both are present, then implementations MUST merge the two
LocalizationData objects before proceeding with the decoration step. In this merge process, nodes in the
localizationData
object take precedence over nodes in the localizationDataUrl object in the case of collisions.
Providers may choose to utilize the two association methods by providing local items using the inclusion method, and global items as well as names (translations that rarely change) using the reference method. It is also permissible for providers to only utilize one of the association methods for both local and global scoped items.
LocalizationData objects are not recursive, and the localizationData and
localizationDataUrl properties can not occur more than once, so there can only ever be a maximum
of two LocalizationData objects associated with an instance document.
Response decoratedInstance = api/decorate/lang {@requestbody unilingualInstance}
... but this would require us to define a schema for the response that adds decoration attributes to all applicable nodes inc scalar
3.4 REST query parameters
1EdTech specifications that utilize the REST protocol SHOULD include the following query parameters in REST operations that return payloads that are eligible for multilingual decoration:
| Name | Description | Type | Cardinality | Implicit Default |
|---|---|---|---|---|
| l12n | Whether to include localizationData and localizationDataUrl
properties in the response. |
Boolean | Optional | False (do not include) |
| l12n-lang | Which languages to include in the localizationData object, if
available and if l12n is set to true.
|
Array of LanguageCode |
Optional | Include all available languages |
Providers that interpret the l12n-lang query parameter MUST use the rules defined in [RFC4647]
for comparing and matching of language tags.
3.5 Error Handling (Consumers)
Implementations that consume LocalizationData objects SHOULD apply the following error recovery behavior:
-
If a GET request to localizationDataUrl does not return a 200 response code and a LocalizationData object
response body, proceed as if the
localizationDataUrlproperty was not present in the source document. - If the path expression given in the LocalizationItem
selectproperty is syntactically invalid, ignore this item and proceed with the next LocalizationItem, if any. - If applying the path expression given in the LocalizationItem
selectproperty returns a collection with zero members, ignore this item and proceed with the next LocalizationItem, if any. - If applying the path expression given in the LocalizationItem
selectproperty returns a collection where one or several members are not scalar, ignore each such member and proceed with the next member, if any.
3.6 Multilinguality Data Model
3.6.1 LocalizedString
A String with an associated language code.
| Property | Type | Description | Multiplicity |
|---|---|---|---|
| language | LanguageCode | The primary language used in the described entity. | [1] |
| value | String | [1] |
3.6.2 LocalizationItem
A localization item, consisting of a node selector and a collection of localized strings
| Property | Type | Description | Multiplicity |
|---|---|---|---|
| select | SelectorExpression | A selector expression targeting one or several nodes in the associated document | [1] |
| apply | LocalizedString |
Localization values applicable to the selected nodes. Each item in the collection of values MUST have a unique language value.
|
[1..*] |
3.6.3 LocalizationData
A container for localization data
| Property | Type | Description | Multiplicity |
|---|---|---|---|
| local | LocalLocalizationData | Localization items that apply to values of nodes in this document instance only | [0..1] |
| global | GlobalLocalizationData | Localization items that apply to nodes in any document of this type | [0..1] |
3.6.4 LocalLocalizationData
Localization items that apply to values of nodes in this document instance only
| Property | Type | Description | Multiplicity |
|---|---|---|---|
| items | LocalizationItem | A collection of LocalizationItem | [1..*] |
3.6.5 GlobalLocalizationData
Localization items that apply to nodes in any document of this type
| Property | Type | Description | Multiplicity |
|---|---|---|---|
| names | DatedLocalizationItems | Localization items that apply to names of nodes in any document of this type | [0..1] |
| values | DatedLocalizationItems | Localization items that apply to values of nodes in any document of this type | [0..1] |
3.6.6 DatedLocalizationItems
Localization items with a timestamp signalling when the item collection was last updated
| Property | Type | Description | Multiplicity |
|---|---|---|---|
| dateLastModified | DateTimeZ | A timestamp describing when this record was last modified. | [1] |
| items | LocalizationItem | A collection of LocalizationItem | [1..*] |
3.6.7 LocalizationDataUrl
The remote localization data entity for this document.
| Property | Type | Description | Multiplicity |
|---|---|---|---|
| dateLastModified | DateTimeZ | A timestamp describing when this record was last modified. | [1] |
| url | URL |
The remote resource. The server MUST respond to a GET operation with a response body that is an instance of LocalizationData.
|
[1] |
3.6.8 LocalizationDataMixin
| Property | Type | Description | Multiplicity |
|---|---|---|---|
| localizationData | LocalizationData | The inlined localization data entity for this document. | [0..1] |
3.6.9 LocalizationDataUrlMixin
| Property | Type | Description | Multiplicity |
|---|---|---|---|
| localizationDataUrl | LocalizationDataUrl | The remote localization data entity for this document. | [0..1] |
3.7 Derived Types
| Type | Description |
|---|---|
| DateTimeZ |
A DateTime with the trailing timezone specifier included, e.g. 2021-09-07T02:09:59+02:00
|
| JsonPathExpression | A JsonPath selector expression [JSONPATH] |
| LanguageCode | A language code [BCP47]. |
| SelectorExpression | A selector expression targeting one or several nodes in the associated document |
| URI |
A NormalizedString that respresents a Uniform Resource Identifier (URI).
|
| URL |
A URI that represents a Uniform Resource Locator (URL).
|
| XPathExpression | An XPath selector expression [XPath]] |
3.8 Primitive Types
| Type | Description |
|---|---|
| DateTime | An [ISO8601] time using the syntax YYYY-MM-DDThh:mm:ss. |
| Language | A language code [BCP47]. |
| NormalizedString |
A String conforming to the normalizedString definition in [XMLSCHEMA-2].
|
| String | Character strings. |
A. Examples
A.1 Multilinguality Module: local scoped value by inclusion
{
"recordLanguage": "en",
"givenName": "Robert",
"familyName": "Smith",
"role": "teacher",
"topics": "geography, mathematics",
"localizationData": {
"local": {
"items": [{
"select": "$.topics",
"apply": [{
"language": "sv",
"value": "geografi, matematik"
}, {
"language": "fr",
"value": "géographie, mathématiques"
}]
}]
}
}
}
A.2 Multilinguality Module: global scoped name and value by reference
The instance Documents:
{
"recordLanguage": "en",
"givenName": "Robert",
"familyName": "Smith",
"role": "teacher",
"topics": "geography, mathematics",
"localizationDataURL": {
"dateLastModified": "2022-11-07T01:02:03+02:00",
"url": "https://example.org/loc001.json"
}
}
... where localizationDataURL resolves to a LocalizationItem with this structure:
{
"global": {
"values": {
"dateLastModified": "2022-11-07T01:02:03+02:00",
"items": [{
"select": "$..[?(@role == 'teacher')]",
"apply": [{
"language": "sv",
"value": "lärare"
}, {
"language": "fr",
"value": "professeur"
}]
}]
},
"names": {
"dateLastModified": "2022-11-07T01:02:03+02:00",
"items": [{
"select": "$.role",
"apply": [{
"language": "sv",
"value": "roll"
}, {
"language": "fr",
"value": "rôle"
}]
}]
}
}
}
B. JSON Schema
LocalizedString
A String with an associated language code.
{
"$schema": "https://json-schema.org/draft/2019-09/schema#",
"$id": "https://purl.imsglobal.org/spec/l12n/v1p0/schema/json/localizedstringv1p0.schema.json",
"title": "JSON Schema for the LocalizedString class.",
"description": "A String with an associated language code.",
"type": "object",
"properties": {
"language": {
"description": "The primary language used in the described entity.",
"$comment": "Origin: LanguageCode (DerivedType); A language code [[BCP47]].",
"type": "string",
"pattern": "^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$"
},
"value": {
"description": "No description supplied.",
"$comment": "Origin: String (PrimitiveType); Character strings.",
"type": "string"
}
},
"required": [
"language",
"value"
],
"additionalProperties": false
}LocalizationItem
A localization item, consisting of a node selector and a collection of localized strings
{
"$schema": "https://json-schema.org/draft/2019-09/schema#",
"$id": "https://purl.imsglobal.org/spec/l12n/v1p0/schema/json/localizationitemv1p0.schema.json",
"title": "JSON Schema for the LocalizationItem class.",
"description": "A localization item, consisting of a node selector and a collection of localized strings",
"type": "object",
"properties": {
"select": {
"description": "A selector expression targeting one or several nodes in the associated document",
"$comment": "Origin: SelectorExpression (DerivedType); A selector expression targeting one or several nodes in the associated document",
"type": "string"
},
"apply": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/LocalizedString"
}
}
},
"required": [
"select",
"apply"
],
"additionalProperties": false,
"$defs": {
"LocalizedString": {
"description": "A String with an associated language code.",
"type": "object",
"properties": {
"language": {
"description": "The primary language used in the described entity.",
"$comment": "Origin: LanguageCode (DerivedType); A language code [[BCP47]].",
"type": "string",
"pattern": "^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$"
},
"value": {
"description": "No description supplied.",
"$comment": "Origin: String (PrimitiveType); Character strings.",
"type": "string"
}
},
"required": [
"language",
"value"
],
"additionalProperties": false
}
}
}LocalizationData
A container for localization data
{
"$schema": "https://json-schema.org/draft/2019-09/schema#",
"$id": "https://purl.imsglobal.org/spec/l12n/v1p0/schema/json/localizationdatav1p0.schema.json",
"title": "JSON Schema for the LocalizationData class.",
"description": "A container for localization data",
"type": "object",
"properties": {
"local": {
"$ref": "#/$defs/LocalLocalizationData"
},
"global": {
"$ref": "#/$defs/GlobalLocalizationData"
}
},
"required": [],
"additionalProperties": false,
"$defs": {
"GlobalLocalizationData": {
"description": "Localization items that apply to nodes in any document of this type",
"type": "object",
"properties": {
"names": {
"$ref": "#/$defs/DatedLocalizationItems"
},
"values": {
"$ref": "#/$defs/DatedLocalizationItems"
}
},
"required": [],
"additionalProperties": false
},
"LocalLocalizationData": {
"description": "Localization items that apply to values of nodes in this document instance only",
"type": "object",
"properties": {
"items": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/LocalizationItem"
}
}
},
"required": [
"items"
],
"additionalProperties": false
},
"LocalizationItem": {
"description": "A localization item, consisting of a node selector and a collection of localized strings",
"type": "object",
"properties": {
"select": {
"description": "A selector expression targeting one or several nodes in the associated document",
"$comment": "Origin: SelectorExpression (DerivedType); A selector expression targeting one or several nodes in the associated document",
"type": "string"
},
"apply": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/LocalizedString"
}
}
},
"required": [
"select",
"apply"
],
"additionalProperties": false
},
"LocalizedString": {
"description": "A String with an associated language code.",
"type": "object",
"properties": {
"language": {
"description": "The primary language used in the described entity.",
"$comment": "Origin: LanguageCode (DerivedType); A language code [[BCP47]].",
"type": "string",
"pattern": "^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$"
},
"value": {
"description": "No description supplied.",
"$comment": "Origin: String (PrimitiveType); Character strings.",
"type": "string"
}
},
"required": [
"language",
"value"
],
"additionalProperties": false
},
"DatedLocalizationItems": {
"description": "Localization items with a timestamp signalling when the item collection was last updated",
"type": "object",
"properties": {
"dateLastModified": {
"description": "A timestamp describing when this record was last modified.",
"$comment": "Origin: DateTimeZ (DerivedType); A `DateTime` with the trailing timezone specifier included, e.g. `2021-09-07T02:09:59+02:00`",
"type": "string",
"format": "date-time"
},
"items": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/LocalizationItem"
}
}
},
"required": [
"dateLastModified",
"items"
],
"additionalProperties": false
}
}
}LocalLocalizationData
Localization items that apply to values of nodes in this document instance only
{
"$schema": "https://json-schema.org/draft/2019-09/schema#",
"$id": "https://purl.imsglobal.org/spec/l12n/v1p0/schema/json/locallocalizationdatav1p0.schema.json",
"title": "JSON Schema for the LocalLocalizationData class.",
"description": "Localization items that apply to values of nodes in this document instance only",
"type": "object",
"properties": {
"items": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/LocalizationItem"
}
}
},
"required": [
"items"
],
"additionalProperties": false,
"$defs": {
"LocalizationItem": {
"description": "A localization item, consisting of a node selector and a collection of localized strings",
"type": "object",
"properties": {
"select": {
"description": "A selector expression targeting one or several nodes in the associated document",
"$comment": "Origin: SelectorExpression (DerivedType); A selector expression targeting one or several nodes in the associated document",
"type": "string"
},
"apply": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/LocalizedString"
}
}
},
"required": [
"select",
"apply"
],
"additionalProperties": false
},
"LocalizedString": {
"description": "A String with an associated language code.",
"type": "object",
"properties": {
"language": {
"description": "The primary language used in the described entity.",
"$comment": "Origin: LanguageCode (DerivedType); A language code [[BCP47]].",
"type": "string",
"pattern": "^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$"
},
"value": {
"description": "No description supplied.",
"$comment": "Origin: String (PrimitiveType); Character strings.",
"type": "string"
}
},
"required": [
"language",
"value"
],
"additionalProperties": false
}
}
}GlobalLocalizationData
Localization items that apply to nodes in any document of this type
{
"$schema": "https://json-schema.org/draft/2019-09/schema#",
"$id": "https://purl.imsglobal.org/spec/l12n/v1p0/schema/json/globallocalizationdatav1p0.schema.json",
"title": "JSON Schema for the GlobalLocalizationData class.",
"description": "Localization items that apply to nodes in any document of this type",
"type": "object",
"properties": {
"names": {
"$ref": "#/$defs/DatedLocalizationItems"
},
"values": {
"$ref": "#/$defs/DatedLocalizationItems"
}
},
"required": [],
"additionalProperties": false,
"$defs": {
"DatedLocalizationItems": {
"description": "Localization items with a timestamp signalling when the item collection was last updated",
"type": "object",
"properties": {
"dateLastModified": {
"description": "A timestamp describing when this record was last modified.",
"$comment": "Origin: DateTimeZ (DerivedType); A `DateTime` with the trailing timezone specifier included, e.g. `2021-09-07T02:09:59+02:00`",
"type": "string",
"format": "date-time"
},
"items": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/LocalizationItem"
}
}
},
"required": [
"dateLastModified",
"items"
],
"additionalProperties": false
},
"LocalizationItem": {
"description": "A localization item, consisting of a node selector and a collection of localized strings",
"type": "object",
"properties": {
"select": {
"description": "A selector expression targeting one or several nodes in the associated document",
"$comment": "Origin: SelectorExpression (DerivedType); A selector expression targeting one or several nodes in the associated document",
"type": "string"
},
"apply": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/LocalizedString"
}
}
},
"required": [
"select",
"apply"
],
"additionalProperties": false
},
"LocalizedString": {
"description": "A String with an associated language code.",
"type": "object",
"properties": {
"language": {
"description": "The primary language used in the described entity.",
"$comment": "Origin: LanguageCode (DerivedType); A language code [[BCP47]].",
"type": "string",
"pattern": "^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$"
},
"value": {
"description": "No description supplied.",
"$comment": "Origin: String (PrimitiveType); Character strings.",
"type": "string"
}
},
"required": [
"language",
"value"
],
"additionalProperties": false
}
}
}B.1 DatedLocalizationItems
Localization items with a timestamp signalling when the item collection was last updated
{
"$schema": "https://json-schema.org/draft/2019-09/schema#",
"$id": "https://purl.imsglobal.org/spec/l12n/v1p0/schema/json/datedlocalizationitemsv1p0.schema.json",
"title": "JSON Schema for the DatedLocalizationItems class.",
"description": "Localization items with a timestamp signalling when the item collection was last updated",
"type": "object",
"properties": {
"dateLastModified": {
"description": "A timestamp describing when this record was last modified.",
"$comment": "Origin: DateTimeZ (DerivedType); A `DateTime` with the trailing timezone specifier included, e.g. `2021-09-07T02:09:59+02:00`",
"type": "string",
"format": "date-time"
},
"items": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/LocalizationItem"
}
}
},
"required": [
"dateLastModified",
"items"
],
"additionalProperties": false,
"$defs": {
"LocalizationItem": {
"description": "A localization item, consisting of a node selector and a collection of localized strings",
"type": "object",
"properties": {
"select": {
"description": "A selector expression targeting one or several nodes in the associated document",
"$comment": "Origin: SelectorExpression (DerivedType); A selector expression targeting one or several nodes in the associated document",
"type": "string"
},
"apply": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/LocalizedString"
}
}
},
"required": [
"select",
"apply"
],
"additionalProperties": false
},
"LocalizedString": {
"description": "A String with an associated language code.",
"type": "object",
"properties": {
"language": {
"description": "The primary language used in the described entity.",
"$comment": "Origin: LanguageCode (DerivedType); A language code [[BCP47]].",
"type": "string",
"pattern": "^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$"
},
"value": {
"description": "No description supplied.",
"$comment": "Origin: String (PrimitiveType); Character strings.",
"type": "string"
}
},
"required": [
"language",
"value"
],
"additionalProperties": false
}
}
}LocalizationDataUrl
The remote localization data entity for this document.
{
"$schema": "https://json-schema.org/draft/2019-09/schema#",
"$id": "https://purl.imsglobal.org/spec/l12n/v1p0/schema/json/localizationdataurlv1p0.schema.json",
"title": "JSON Schema for the LocalizationDataUrl class.",
"description": "The remote localization data entity for this document.",
"type": "object",
"properties": {
"dateLastModified": {
"description": "A timestamp describing when this record was last modified.",
"$comment": "Origin: DateTimeZ (DerivedType); A `DateTime` with the trailing timezone specifier included, e.g. `2021-09-07T02:09:59+02:00`",
"type": "string",
"format": "date-time"
},
"url": {
"description": "The remote resource. The server MUST respond to a GET operation with a response body that is an instance of `LocalizationData`.",
"$comment": "Origin: URL (DerivedType); A `URI` that represents a Uniform Resource Locator (URL).",
"type": "string"
}
},
"required": [
"dateLastModified",
"url"
],
"additionalProperties": false
}LocalizationDataMixin
{
"$schema": "https://json-schema.org/draft/2019-09/schema#",
"$id": "https://purl.imsglobal.org/spec/l12n/v1p0/schema/json/localizationdatamixinv1p0.schema.json",
"title": "JSON Schema for the LocalizationDataMixin class.",
"description": "No description supplied.",
"type": "object",
"properties": {
"localizationData": {
"$ref": "#/$defs/LocalizationData"
}
},
"required": [],
"additionalProperties": false,
"$defs": {
"LocalizationData": {
"description": "A container for localization data",
"type": "object",
"properties": {
"local": {
"$ref": "#/$defs/LocalLocalizationData"
},
"global": {
"$ref": "#/$defs/GlobalLocalizationData"
}
},
"required": [],
"additionalProperties": false
},
"GlobalLocalizationData": {
"description": "Localization items that apply to nodes in any document of this type",
"type": "object",
"properties": {
"names": {
"$ref": "#/$defs/DatedLocalizationItems"
},
"values": {
"$ref": "#/$defs/DatedLocalizationItems"
}
},
"required": [],
"additionalProperties": false
},
"LocalLocalizationData": {
"description": "Localization items that apply to values of nodes in this document instance only",
"type": "object",
"properties": {
"items": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/LocalizationItem"
}
}
},
"required": [
"items"
],
"additionalProperties": false
},
"LocalizationItem": {
"description": "A localization item, consisting of a node selector and a collection of localized strings",
"type": "object",
"properties": {
"select": {
"description": "A selector expression targeting one or several nodes in the associated document",
"$comment": "Origin: SelectorExpression (DerivedType); A selector expression targeting one or several nodes in the associated document",
"type": "string"
},
"apply": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/LocalizedString"
}
}
},
"required": [
"select",
"apply"
],
"additionalProperties": false
},
"LocalizedString": {
"description": "A String with an associated language code.",
"type": "object",
"properties": {
"language": {
"description": "The primary language used in the described entity.",
"$comment": "Origin: LanguageCode (DerivedType); A language code [[BCP47]].",
"type": "string",
"pattern": "^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$"
},
"value": {
"description": "No description supplied.",
"$comment": "Origin: String (PrimitiveType); Character strings.",
"type": "string"
}
},
"required": [
"language",
"value"
],
"additionalProperties": false
},
"DatedLocalizationItems": {
"description": "Localization items with a timestamp signalling when the item collection was last updated",
"type": "object",
"properties": {
"dateLastModified": {
"description": "A timestamp describing when this record was last modified.",
"$comment": "Origin: DateTimeZ (DerivedType); A `DateTime` with the trailing timezone specifier included, e.g. `2021-09-07T02:09:59+02:00`",
"type": "string",
"format": "date-time"
},
"items": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/LocalizationItem"
}
}
},
"required": [
"dateLastModified",
"items"
],
"additionalProperties": false
}
}
}LocalizationDataUrlMixin
{
"$schema": "https://json-schema.org/draft/2019-09/schema#",
"$id": "https://purl.imsglobal.org/spec/l12n/v1p0/schema/json/localizationdataurlmixinv1p0.schema.json",
"title": "JSON Schema for the LocalizationDataUrlMixin class.",
"description": "No description supplied.",
"type": "object",
"properties": {
"localizationDataUrl": {
"$ref": "#/$defs/LocalizationDataUrl"
}
},
"required": [],
"additionalProperties": false,
"$defs": {
"LocalizationDataUrl": {
"description": "The remote localization data entity for this document.",
"type": "object",
"properties": {
"dateLastModified": {
"description": "A timestamp describing when this record was last modified.",
"$comment": "Origin: DateTimeZ (DerivedType); A `DateTime` with the trailing timezone specifier included, e.g. `2021-09-07T02:09:59+02:00`",
"type": "string",
"format": "date-time"
},
"url": {
"description": "The remote resource. The server MUST respond to a GET operation with a response body that is an instance of `LocalizationData`.",
"$comment": "Origin: URL (DerivedType); A `URI` that represents a Uniform Resource Locator (URL).",
"type": "string"
}
},
"required": [
"dateLastModified",
"url"
],
"additionalProperties": false
}
}
}C. Revision History
| Version No. | Release Date | Comments |
|---|---|---|
| First preview draft | November 6, 2022 | First preview draft release for early review by Edu-API working group |
D. References
D.1 Normative references
- [BCP47]
- Tags for Identifying Languages. A. Phillips, Ed.; M. Davis, Ed.. IETF. September 2009. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc5646
- [ISO8601]
- Representation of dates and times. ISO 8601:2004.. International Organization for Standardization (ISO). 2004. ISO 8601:2004. URL: http://www.iso.org/iso/catalogue_detail?csnumber=40874
- [JSONPATH]
- JSONPath: Query expressions for JSON. IETF. 17 October 2022. URL: https://datatracker.ietf.org/doc/draft-ietf-jsonpath-base/
- [RFC2119]
- Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
- [RFC4647]
- Matching of Language Tags. A. Phillips, Ed.; M. Davis, Ed.. IETF. September 2006. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc4647
- [XMLSCHEMA-2]
- XML Schema Part 2: Datatypes Second Edition. Paul V. Biron; Ashok Malhotra. W3C. 28 October 2004. W3C Recommendation. URL: https://www.w3.org/TR/xmlschema-2/
D.2 Informative references
- [CDM]
- 1EdTech Common Data Model (CDM). 1EdTech. 17 October 2022. URL: https://datamodels-staging.imsglobal.org
- [json-ld11]
- JSON-LD 1.1. Gregg Kellogg; Pierre-Antoine Champin; Dave Longley. W3C. 16 July 2020. W3C Recommendation. URL: https://www.w3.org/TR/json-ld11/
- [RFC3282]
- Content Language Headers. H. Alvestrand. IETF. May 2002. Draft Standard. URL: https://www.rfc-editor.org/rfc/rfc3282
- [xpath-30]
- XML Path Language (XPath) 3.0. Jonathan Robie; Don Chamberlin; Michael Dyck; John Snelson. W3C. 8 April 2014. W3C Recommendation. URL: https://www.w3.org/TR/xpath-30/
E. List of Contributors
The following individuals contributed to the development of this document:
| Name | Organization | Role |
|---|---|---|
| Markus Gylling | 1EdTech | Editor |