-
Notifications
You must be signed in to change notification settings - Fork 0
Properties Schema
- What is properties.schema?
- Constructing a properties.schema
- Options for Input Types
- Options for Data Validation
###What is properties.schema?
properties.schema is a JSON file that is provided by a plug-in. It is the point of contact between the authoring tool, the plug-in, and the course author who configures it. It tells the Adapt authoring tool what configuration data is required from the course author in order to make the plug-in work. It specifies the type of field input the authoring tool should use to gather that data. And in some cases, it directs the type of data validation should be performed upon submit. Every property that appears in the plug-in's model that is intended to be configured by the course author must appear in the properties.schema. If a model attribute is not configured by the course author using the authoring tool, the plug-in’s JavaScript code must assign to the attribute a default value.
properties.schema is based on JSON Schema draft-04. JSON Schema isn’t explained here, but it should be referenced for more detail or for situations not covered in this article.
####The value of a quality example.json
In the Adapt framework, the course author configures plug-ins (extensions, components, menu, theme) by assigning values in the following course JSON files: config.json, course.json, componentObjects.json, articles.json, blocks.json, and components.json. In which file the property resides is determined largely by the type of plug-in and the scope of its effects. The plug-in’s example.json provides a model of its configurable properties. If necessary, the example.json also specifies which course JSON file the properties should be added to. (maybe an image with a snippet of example.json.)
In the Adapt authoring tool, the course author does not directly edit these course JSON files. The tool uses an interface—based on properties.schema—to capture values for the same properties specified in example.json. For this reason, it is highly recommended that you reference an accurate example.json of your plug-in while constructing its properties.schema.
####Describing properties that are primitives
In JSON, primitives (number, string, and Boolean) are represented by a single key/value pair. Both the key and its value are represented by properties.schema. "body"
is a typical attribute of an Adapt component. Its value is always string data. In example.json it look like this:
“body”: “This is some body text.”
In properties.schema it is typically described like this:
"body": {
"type": "string",
"required": true,
"inputType": "TextArea",
"title": "Item Body",
"default": "",
"validators": ["required"],
"help": "This is the item body text that is hidden until the item title is clicked on"
}
In the example above, "body"
is modeled as an object. Some of its properties describe the data value (metadata), and some describe how it will be captured by the authoring tool. This is the model used with JavaScript primitives: numbers, strings, and Booleans.
type (string): The JavaScript data-type of the expected value. One of "string"
, "number"
, "boolean"
, 'object"
, or "array"
.
required (boolean): Whether or not this property must have a value. If set to true
, the user interface forces the course author to provide input. If set to false
, no input is required from the author; the default value will be used.
inputType (string): The type of input field that the authoring tool will use to collect the configuration data from the course author. The types of input fields are associated with standard HTML form elements, such as text boxes and drop-down lists. The supplied value must conform to the constants and patterns expected by the authoring tool. Further explanation and descriptions are found below in Options for Input Types.
title (string): This is displayed as the label for the input type.
default (data-type varies): This value is used if the course author does not specify a value. Use ""
to represent the empty string when a more specific value is not required.
validators (string array): One or more string constants representing the kinds of validation that should be performed on the data when it is submitted. Acceptable values include "required"
and "number"
. Separate multiple values with a comma. Use []
to represent an empty array when no validators are necessary.
help (string): Brief text intended to guide the course author in specifying configuration values. It is displayed below the Title.
####Describing properties that are objects
In JSON, objects and arrays are represented by nesting a key/value pair within a value. Likewise properties.schema makes use of nested descriptions with objects and arrays. "_graphic"
is a typical object that is used to collect properties of a component’s image. In example.json it looks like this:
"_graphic": {
"src": "hot_graphic.jpg",
"alt": "alt text"
}
In properties.schema it is typically described like this:
"_graphic": {
"type": "object",
"required": false,
"title": "Main hotgraphic",
"properties": {
"src": {
"type": "string",
"required": true,
"default": "",
"inputType": "Asset:image",
"validators": ["required"],
"help": "This is the image that appears behind the pins"
},
"alt": {
"type": "string",
"required": false,
"default": "",
"inputType": "Text",
"validators": [],
"help": "Alternative text for this image read by screen readers"
}
}
}
The list of key/value pairs that describe “_graphic”
is terminated by the key “properties”
which holds object descriptions of "_graphic"
’s two properties. Because "src"
and "alt"
are primitive data-types (string), their descriptions employ the model used above for "body"
.
####Describing properties that are arrays
Some components, such as the core Text and Graphic components, are comprised of non-repeating attributes. Other core plug-ins, such as Accordion and Narrative, have elements that repeat. Each of its repeating items has the same set of properties. The schema is not concerned with how many items the course author might want. It is only concerned with the properties of the repeating item and with the array that stores them.
Like objects explained above, arrays are represented by nesting a key/value pair within a value.
"_items"
is a typical array that is used to store items such as the expandable items of the Accordion. In example.json it looks like this:
"_items": [
{
"title": "Heading 1",
"body": "This is display text 1.",
"_graphic": {
"src": "course/en/images/example.jpg",
"alt": "accordion item 1 graphic alt text here."
}
}
]
In properties.schema it is typically described like this:
"_items": {
"type": "array",
"required": true,
"title": "Items",
"items": {
"type": "object",
"required": true,
"properties": {
"title": {
"type": "string",
"required": true,
"inputType": "Text",
"title": "Item Title",
"default": "",
"validators": ["required"],
"help": "This is the item title"
},
"body": {
"type": "string",
"required": true,
"inputType": "TextArea",
"title": "Item Body",
"default": "",
"validators": ["required"],
"help": "This is the item body text that is hidden until the item title is clicked on"
},
"_graphic": {
"type": "object",
"required": false,
"title": "Graphic",
"properties":{
"alt": {
"type": "string",
"required": false,
"default": "",
"inputType": "Text",
"validators": [],
"help": "The alternative text for this image"
},
"src": {
"type": "string",
"required": false,
"default": "",
"inputType": "Asset:image",
"validators": [],
"help": "Optional image which will be rendered with the item body text"
}
}
}
}
}
}
Unlike the object explored previously, the array does not have a "properties"
attribute. Instead it uses "items"
.
Caution: Avoid confusing
"_items"
with"item"
."_items"
is a key established by the plug-in's source code. The developer could have chosen another identifier such as"_stages"
,"_widgets"
, or"_tabs"
as long as the same identifier was used in the code to access this value. The"items"
that appears in line with the keys that precede it—"type"
,"required"
,"title"
—is not an arbitrary term. It must be used in conjunction with"type": "array"
.
The value of "items"
is determined by the data type of the item. If each item is simply a word or phrase, it can follow the model set in Describing properties that are primitives. Most likely the item will be an object and should be described according to the model set in Describing properties that are objects. In the code example above, "items"
is indeed an object. Its "properties"
key identifies two string properties ("title"
and "body"
) and one object property ("_graphic"
). "_graphic"
, as an object itself, provides a description of its properties, too.
The nesting involved with these descriptions can get confusing. Remember that "type": "object"
is paired with "properties"
and "type": "array"
with "items"
. And remember that no description is complete until complex data types have been described by their primitive components.
###Constructing a properties.schema
Keep two objectives in mind when creating a properties.schema:
- constructing the nested models that ultimately terminate in descriptions of primitive data types
- supplying the models with values appropriate for a user interface
Note: Presenting a complete schema as a universal example is problematic. Instead you are encouraged to reference the properties.schema of the core Adapt plug-ins.
####Header
The document begins with the following lines:
{
"type":"object",
"$schema": "http://json-schema.org/draft-04/schema",
"id": "http://jsonschema.net",
"$ref": "http://localhost/plugins/content/component/model.schema",
The value of “$ref”
depends on the type of plug-in. Substitute where appropriate.
- component:
"http://localhost/plugins/content/component/model.schema"
- menu:
"http://localhost/plugins/content/contentobject/model.schema"
- theme:
"http://localhost/plugins/content/theme/model.schema"
- extension: None. Omit the entire
“$ref”
key/value pair. Replace it with"required": false,
. The Boolean value you supply,true
orfalse
, reflects whether or not the extension must be configured by the course author.
####"globals"
[introductory text explaining globals in general and accessibility via ariaRegions, ariaPopupLabels] Accessibility is an important issue in the world today, and Adapt has embraced accessibility solutions within its core modules. We hope every developer of Adapt plug-ins will do so, too.
"globals": {
"ariaRegion": {
"type": "string",
"required": true,
"default": "This component is an accordion comprised of collapsible content panels containing display text. Select the item titles to toggle the visibility of these content panels.",
"inputType": "Text",
"validators": []
}
},
####"properties"
The Adapt framework requires that plug-ins have certain properties based on the plug-in's type: component, extension, theme, or menu. These required properties presented to the course author by the authoring tool itself. ("_supportedLayout"
is an exception that will be addressed shortly.) The plug-in developer does not need to include the following component properties in the properties.schema: "_componentType"
, "_type"
, "_component"
, "_layout"
, "_classes"
, "_isOptional"
, "_parentId"
, "_courseId"
, "title"
, "displayTitle"
, and "body"
. The most current list is maintained in code in component/model.schema. Properties for other plug-in types can be found by investigating extension/extensiontype.schema, menu/menutype.schema, and theme/model.schema.
After "globals"
the schema lists the configurable properties of the plug-in.
"properties": {
"_supportedLayout": {
"type": "string",
"required": true,
"enum": ["full-width", "half-width", "both"],
"default": "half-width",
"editorOnly": true
},
"instruction": {
"type": "string",
"required": false,
"default": "",
"inputType": "Text",
"validators": [],
"help": "This is the instruction text"
},
The first property, "_supportedLayout"
, is required by the authoring tool. It is associated with the "_layout"
property that appears in the Adapt framework. The values listed in the "enum"
determine the layout options presented to the course author. "full-width"
allows the author to position the component to span the width of the page. "half-width"
gives the author the option of positioning it either on the left or right side. And "both"
provides the author with all three options. The developer specifies values only for "enum"
and "default"
; all other keys and values must remain as presented above.
####Options for Input Types
"inputType": "Text"
"inputType": {"type": "Boolean", "options": [true, false]}
"inputType": "Asset:image"
"inputType": "Asset:video"
"inputType": "Asset:audio"
"inputType": “Asset:other” (PDFs, docs, etc.)
"inputType": "TextArea"
"inputType": "Number" "validators": ["number"],
"inputType": { "type": "Select", "options": ["document", "media", "link”]}
"inputType": {"type": "Select", "options":["inview", "allItems"]}
"inputType": {"type": "Select", "options":["hidden", "visible"]}
"inputType": {"type": "Select", "options":["page", "block", "component"]}
"inputType": { "type": "Select", "options": ["document", "media", "link"]}
"inputType": "QuestionButton" (textInput) Are values case-sensitive? Can new types be proposed to the authoring tool?
Does every Select require an "enum"? e.g., "enum": ["inview", "allItems"]
Boolean input does not require an enum.
Every input must supply a default, though String can be an empty string.
"enum": ["full-width", "half-width", "both"], "default": "full-width", "editorOnly": true
"type": "boolean"
"type": "number"
"type": "array"
"type": "string"
"type": "object"
"type" must match the options presented in Select.
? Can Select options only be string? Can they be Number? (Boolean has its own inputType)?
"default": 60
####Options for Data Validation
"validators": ["number"]
"validators": ["required"] ?use with "required":true?
"validators": ["required", "number"]
Notes for composition:
- reference core plug-ins as models
- must address use with extensions
- provide a very low level step-by-step: 1) copy example.json; 2) delete the following properties: _id,_parentId, etc; the remaining properties must be addressed in your schema; 3) for each property and each property of an object or array, paste the following model over the property's value; 4) referencing your original example.json, add values to the model's keys...
{
"type":"object",
"$schema": "http://json-schema.org/draft-04/schema",
"id": "http://jsonschema.net",
"$ref": "http://localhost/plugins/content/component/model.schema",
"properties":{
"instruction": {
"type":"string",
"title": "Instruction text"
},
"_attempts": {
"type":"number",
"required":true,
"default":1,
"minimum": 1,
"title": "Number of attempts"
},
"_isRandom": {
"type":"boolean",
"required":true,
"default":false,
"title": "Random order"
},
"_questionWeight": {
"type":"number",
"required":false,
"title":"Question weight"
},
"_selectable": {
"type":"number",
"required":true,
"minimum": 1,
"default":1,
"title": "Number of items to select"
},
"_buttons": {
"type":"object",
"title": "Buttons",
"properties":{
"hideCorrectAnswer": {
"type":"string",
"title": "Hide correct answer button label"
},
"reset": {
"type":"string",
"title": "Reset button label"
},
"showCorrectAnswer": {
"type":"string",
"title": "Show correct answer button label"
},
"submit": {
"type":"string",
"title": "Submit button label"
}
}
},
"_feedback": {
"type":"object",
"required":true,
"title": "Feedback text",
"properties":{
"_incorrect": {
"type":"object",
"required":true,
"title": "Feedback for incorrect answers",
"properties":{
"final": {
"type":"string",
"required":true,
"minLength": 1,
"title": "Incorrect final answer"
},
"notFinal": {
"type":"string",
"title": "Incorrect non final answer"
}
}
},
"_partlyCorrect": {
"type":"object",
"required":true,
"title": "Feedback when answer is partly correct",
"properties":{
"final": {
"type":"string",
"required":true,
"title": "Partially correct final answer",
"minLength": 1
},
"notFinal": {
"type":"string",
"title": "Partially correct non final answer"
}
}
},
"correct": {
"type":"string",
"required":true,
"title": "Feedback for correct answer",
"minLength": 1
}
}
},
"_items": {
"type":"array",
"required":true,
"minItems": 1,
"maxItems": 8,
"title": "Answers",
"items": {
"type":"object",
"required":true,
"properties":{
"_graphic": {
"type":"object",
"required":true,
"title": "Graphic",
"properties":{
"alt": {
"type":"string",
"required":false,
"title": "Alternative text"
},
"large": {
"type":"string",
"required":true,
"title": "Large graphic asset",
"minLength": 1
},
"small": {
"type":"string",
"required":true,
"title": "Small graphic asset",
"minLength": 1
},
"title": {
"type":"string",
"required":true,
"title": "Graphic title",
"minLength": 1
}
}
},
"_shouldBeSelected": {
"type":"boolean",
"required":true,
"default":false,
"title": "Correct answer"
},
"text": {
"type":"string",
"required":false,
"title": "Answer text"
},
"feedback": {
"type":"string",
"required":false,
"title": "Incorrect answer feedback (Number of items to select must be 1)"
}
}
}
}
}
}

- Framework in Five Minutes
- Setting up Your Development Environment
- Manual Installation of the Adapt Framework
- Adapt Command Line Interface
- Common Issues
- Adapt API
- Adapt Command Line Interface
- Core Events
- Core Model Attributes
- Core Modules
- Peer Code Review