1EdTech Localization Framework

1EdTech Localization Framework

Base Document
Spec Version 1.0
Base Document
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).
Note

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.

Figure 1 Example of a LocalizedString object
{
  "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.

Figure 2 Example of a LocalizationItem object
{
  "select": "...selector expression... ",
  "apply": [
    {
      "language": "ar-ER",
      "value": "...string..."
    },
    {
      "language": "yue",
      "value": "...string..."
    }
  ]
}
          
Issue 1
Fix select expression in sample autogenerator; should not be null

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 dateLastModified timestamp 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 dateLastModified timestamp 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)
    }
  }
}
          
Figure 3 Example of a LocalizationData object

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 localizationData property.
By reference
The LocalizationData object is referenced at a remote location using localizationDataUrl property.
Issue 2
TODO 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.

Note

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.

Note

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.

Issue 3
An alternative might to use a REST API, endpoint declared in discovery API, to decorate the instance, e.g:
Response decoratedInstance = api/decorate/lang {@requestbody unilingualInstance}              
        
Figure 4 Fictional REST api for multilingual decoration

... 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:

REST operation query parameters
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 localizationDataUrl property was not present in the source document.
  • If the path expression given in the LocalizationItem select property is syntactically invalid, ignore this item and proceed with the next LocalizationItem, if any.
  • If applying the path expression given in the LocalizationItem select property 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 select property 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"
        }]
      }]
    }
  }
}         
        
Figure 5 Example of applying a LocalizationItem to the person.topics value using an inline LocalizationData object.

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"
        }]
      }]
    }
  }
}

            
Figure 6 Example of applying a LocalizationItem to the person.role name and value using a remote LocalizationData object.

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
This is a preview of the 1EdTech Localization Framework v1.0

This version is made available to enable early review. Do not reference this document as normative in any way. This document should be considered a work in progress until it is final.

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 Gylling1EdTechEditor

1EdTech™ Consortium, Inc. ("1EdTech") is publishing the information contained in this document ("Specification") for purposes of scientific, experimental, and scholarly collaboration only.

1EdTech makes no warranty or representation regarding the accuracy or completeness of the Specification.

This material is provided on an "As Is" and "As Available" basis.

The Specification is at all times subject to change and revision without notice.

It is your sole responsibility to evaluate the usefulness, accuracy, and completeness of the Specification as it relates to you.

1EdTech would appreciate receiving your comments and suggestions.

Please contact 1EdTech through our website at www.1edtech.org.

Please refer to Document Name: 1EdTech Localization Framework 1.0

Date: November 6, 2022