learnosity / learnosity-qti
Learnosity QTI Conversion Library
Installs: 7 181
Dependents: 0
Suggesters: 0
Security: 0
Stars: 21
Watchers: 54
Forks: 22
Open Issues: 9
Requires
- php: >=7.4
- learnosity/learnosity-sdk-php: >=1
- qtism/qtism: ^19.0
- symfony/config: ^3.4
- symfony/console: ^3.4
- symfony/dependency-injection: ^3.4
- symfony/finder: ^3.4
- symfony/http-foundation: ^5
- symfony/yaml: ^3.4
Requires (Dev)
- phpunit/phpunit: ^4.8
- dev-develop
- v2.1.0
- v2.0.1
- v2.0.0
- v2.0.0-beta
- v2.0.0-alpha
- v1.2.x-dev
- v1.2.1
- v1.2.0
- v1.1.0
- v1.0.0
- v0.9.0
- v0.8.0
- v0.7.0
- v0.6.1
- v0.6.0
- v0.5.0
- dev-master
- dev-LRN-38975/POLISH/make-autoloading-psr4-compatibile
- dev-Learnosity/change/php70-minimum-requirement
- dev-release/v2.0.0-theta
- dev-Learnosity/feature/travis-ci
- dev-update-learnosity-sdk-version
- dev-Learnosity/tests/add-export-coverage
- dev-Learnosity/docs/contribution-guide
This package is auto-updated.
Last update: 2024-10-24 23:02:49 UTC
README
This library is open source and currently is not actively maintained by Learnosity.
Users should fork this repository to fix any issues found or feature requests required.
--
Learnosity QTI
This package converts between QTI 2.1 Assessment Items and Learnosity JSON.
You can choose between 2 main jobs:
convert:to:learnosity
- Converts QTI v2.1 to Learnosity JSONconvert:to:qti
- Converts Learnosity JSON to QTI v2.1
Installation via Composer
Using Composer is the recommended way to install Learnosity QTI for PHP. In order to use the package with Composer, you must add "learnosity/learnosity-qti" as a dependency in your project's composer.json file.
{
"require": {
"learnosity/learnosity-qti": "2.*"
}
}
Then, install your dependencies
composer install
Or just do:
composer global require "learnosity/learnosity-qti"
For bleeding edge:
{
"require": {
"learnosity/learnosity-qti": "dev-develop"
}
}
Make sure to add $HOME/.composer/vendor/bin directory to your $PATH so the mo
executable can be located by your system. If not, simply replace all mo
commands below with ./bin/mo
(from the root of the project).
This package has been tested on PHP 7.4+
Usage
The mo
command line runner
Use the command line tool, mo
to run conversion jobs. To see all jobs, run mo list
:
$ mo list
Usage:
mo [command] [options] [--help]
Flags:
--help Print the applications help
Commands:
convert:to:learnosity Converts QTI v2.1 to Learnosity JSON
convert:to:qti Converts Learnosity JSON to QTI v2.1
list Lists all commands available
Converting QTI to Learnosity JSON
By default, Learnosity QTI expects a QTI content package, including an imsmanifest.xml.
To convert QTI 2.1 to Learnosity JSON, run the following:
mo convert:to:learnosity --organisation_id [integer]
organisation_id
is a mandatory option, where the value is an integer of your Learnosity item bank (organisation).
By default this will look for content packages inside the ./data/input
directory, and output raw results to ./data/output/raw
and final item JSON to ./data/output/final
. A job manifest file will be written to ./data/output/log
, indicating errors or warnings found during the conversion.
Note that only the data
folder is present in this repository, you can create the data/input
folder to add content packages there. The data/output
path will be created automatically if you don't override via input options.
Conversion options
If you want to use different input and/or output paths you can use options:
mo convert:to:learnosity --input /my/path/to/qti --output /my/path/to/output/folder --organisation_id [integer]
All supported input options are as follows:
Assets
The conversion library will update any asset URL inside QTI content to use the fololwing Learnosity CDN address:
https://assets.learnosity.com/organisations/[integer]/[filename]
The organisation
value is taken from the --organisation_id
input parameter passed to the command line.
Supported file types include:
- images
- audio files (mp3)
- video files (mp4)
When importing content using the Data API, you can add files using the Upload Assets endpoint.
Metadata (LOM)
Metadata will be taken from the content package manifest and converted to Learnosity tags. The format is assumed to be:
<imsmd:lom>
<imsmd:classification>
<imsmd:taxonPath>
<imsmd:source>
<imsmd:string xml:lang="en">GradeLevel</imsmd:string>
</imsmd:source>
<imsmd:taxon>
<imsmd:entry>
<imsmd:string xml:lang="en">6</imsmd:string>
</imsmd:entry>
</imsmd:taxon>
</imsmd:taxonPath>
</imsmd:classification>
</imsmd:lom>
This will be converted to the following Learnosity JSON (snippet only):
{
"tags": {
"GradeLevel": [
"6"
]
}
}
Note that <imsmd:source>
translates to Learnosity tag types, and <imsmd:taxon>
translates to tag names.
Supported Interactions - QTI to Learnosity
The following QTI v2.1 interactions are supported:
Rubrics
<rubricBlock>
elements are commonplace in QTI documents. Learnosity can treat these as:
- passages
- distractor rationale
- rating question types (for scoring)
Passages
Learnosity has the concept of a Passage, which is a separate HTML fragment that can be added to single items, or shared across multiple items. By default, the conversion library looks for the following QTI to be converted into a passage:
<rubricBlock use="context" view="candidate author proctor scorer testConstructor tutor">
<div>
<object data="../passages/passage.html" type="text/html" />
</div>
</rubricBlock>
In the example above, the contents of the passage come from an external file in the content package. You can also include the passage contents inline (inside the <rubricBlock>
element).
Note that the use
attribute must be context
, and the view
attribute must include candidate
.
The Learnosity JSON generated would contain 2-columns, the passage(s) in the left and the question(s) in the right.
Multiple passages
If 2 passages are found in a QTI item, a tabbed interface will appear in the converted JSON (in the left-column).
If 3 (or more) passages are found, they will be stacked vertically in the UI (no tabs).
"Shared" Passages
In the converted results, the Learnosity reference (unique identifier) to a passage is generated from a hash of the passage body. So, we automatically "share" a passage if an exact match is found based on the contents of the passage.
Distractor rationale
Students
If the use
attribute of a <rubricBlock>
element is rationale
, and the view
attribute contains candidate
, the conversion library will generate distractor_rationale_response_level
inside the question metadata.
The contents of the <rubricBlock>
will be broken down by block elements, one for each array element of distractor_rationale_response_level
. Eg:
<rubricBlock use="rationale" view="candidate">
<p><span">Distractor:</span> Natoque velit etiam sem varius consequat.</p>
<p><span">Distractor:</span> Enim vestibulum habitant dui ut morbi.</p>
<p><span">Correct: </span>Dapibus scelerisque diam lacus nec lacus.</p>
<p><span">Distractor:</span> Himenaeos fringilla arcu suspendisse pulvinar.</p>
</rubricBlock>
Would generate the following JSON:
{
"metadata": {
"distractor_rationale_response_level": [
"<p><span>Distractor:</span> Natoque velit etiam sem varius consequat.</p>",
"<p><span>Distractor:</span> Enim vestibulum habitant dui ut morbi.</p>",
"<p><span>Correct: </span>Dapibus scelerisque diam lacus nec lacus.</p>",
"<p><span>Distractor:</span> Himenaeos fringilla arcu suspendisse pulvinar.</p>"
]
}
}
If <feedbackInline>
elements are found, they will be converted to distractor_rationale_response_level
. Eg with the following for a choice interaction:
<choiceInteraction responseIdentifier="RESPONSE" maxChoices="1" shuffle="false">
<prompt>
[Question prompt here]
</prompt>
<simpleChoice identifier="A">
<feedbackInline identifier="feedback6399842" outcomeIdentifier="FEEDBACK" showHide="show">
<object data="71de4a8f-b3c6-4518-99dd-668774d507de.html" type="text/html" />
</feedbackInline>
<object data="25d4c6ed-ae48-4bc1-b0b7-550616080534.html" type="text/html" />
</simpleChoice>
<simpleChoice identifier="B">
<object data="72e8b863-03d3-4c1c-84bd-1d944c563fd2.html" type="text/html" />
</simpleChoice>
<simpleChoice identifier="C">
<feedbackInline identifier="feedback6399844" outcomeIdentifier="FEEDBACK" showHide="show">
<object data="37665b88-75fa-45a9-bf1d-a1bd675c7657.html" type="text/html" />
</feedbackInline>
<object data="a819c432-90f0-47c8-a13b-d341582bf86d.html" type="text/html" />
</simpleChoice>
<simpleChoice identifier="D">
<feedbackInline identifier="feedback6399845" outcomeIdentifier="FEEDBACK" showHide="show">
<object data="c5b5531d-bb61-4965-82a9-189edfaa15cb.html" type="text/html" />
</feedbackInline>
<object data="80fff1a9-1351-46f5-b69b-ab817dd95d58.html" type="text/html" />
</simpleChoice>
</choiceInteraction>
The feedbackInline
contents will be converted to distractor_rationale_response_level
array elements.
Graders
If the class
attribute of a <rubricBlock>
element is DistractorRationale
, and the view
attribute contains author
, the conversion library will generate distractor_rationale_scorer
as a custom metadata field inside the question metadata.
The contents of the <rubricBlock>
will be used, eg:
<rubricBlock class="DistractorRationale" view="author">
<p>Parturient est morbi suspendisse nisi a duis scelerisque integer ut...</p>
</rubricBlock>
Would generate the following JSON:
{
"metadata": {
"distractor_rationale_scorer": "<p>Parturient est morbi suspendisse nisi a duis scelerisque integer ut...</p>"
}
}
It would up to the host page calling the Assessment API to render this content to a grader.
Unsupported
Learnosity QTI does not support:
<assessmentItem>
with no interactions (passage-only or rubric-only)- Custom CSS stylesheets. These must be loaded separately at run time for the host page initialising the Assessment API.
Note that only <assessmentItem>
are supported, no other QTI elements like <assessmentTest>
.
Help
Remember you can ask for help
:
$ mo convert:to:learnosity --help
Usage:
convert:to:learnosity [options]
Options:
-i, --input=INPUT The input path to your QTI content [default: "./data/input"]
-o, --output=OUTPUT An output path where the Learnosity JSON will be saved [default: "./data/output"]
--organisation_id=ORGANISATION_ID The identifier of the item bank you want to import content into [default: ""]
--item-reference-source[=ITEM-REFERENCE-SOURCE] The source to use to extract the reference for the item. Valid values are the following:
item - uses the identifier attribute on the <assessmentItem> element
metadata - uses the <identifier> element from the LOM metadata in the manifest, if available. If
no <identifier> is found, then this parameter operates in "item" mode
resource - uses the identifier attribute on the <resource> element in the manifest
filename - uses the basename of the <assessmentItem> XML file
[default: "metadata"]
--passage-only-items[=PASSAGE-ONLY-ITEMS] If you pass the value as "Y", the conversion library will convert regular assessment items as well
as passage-only items, if defined in the manifest [default: "N"]
--single-item[=SINGLE-ITEM] If you pass the value as "Y", the conversion library will convert only single xml file [default: "N"]
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Help:
Converts QTI v2.1 to Learnosity JSON, expects to run on folder(s) with a imsmanifest.xml file
Importing into Learnosity
Once you have Learnosity JSON (the final
folder), you can use the Data API to import into your Learnosity hosted item bank.
Example of the output format is:
{
"qtiitems": {
"[item-reference]": {
"item": {},
"questions": [],
"features": [],
"manifest": [],
"rubric": null,
"assumptions": []
}
}
}
Loop over all item objects inside qtiitems
.
Inside each item object, import the questions (setQuestions) and features (setFeatures) first, then the item (setItems). Setting items will automatically import any tags that were in the manifest.
Converting Learnosity JSON to QTI
To convert Learnosity JSON to QTI 2.1, run the following:
mo convert:to:qti
By default this will look for content packages inside the ./data/input
directory, and output raw results to ./data/output/raw
. A manifest file will be written to ./data/output/log
.
Note that only the data
folder is present in this repository, you can create the data/input
folder to add content packages there. The data/output
path will be created automatically if you don't override via input options.
Conversion options
If you want to use different input and/or output paths you can use options:
mo convert:to:qti --input /my/path/to/learnosity-json --output /my/path/to/output/folder
All supported input options are as follows:
Learnosity JSON format
This conversion tool expects to be given JSON in the format that is returned by the offline package endpoint of the Data API. The Data API itembank/offlinepackage
endpoint returns Activities/Items/Questions/Features in a single directory. It also contains any assets, including images, audio or video, that are part of the content.
The directory returned from the itembank/offlinepackage endpoint contains the following files:
Learnosity/
itembank/
activities/
hashedfilename.json
assets/
image1.jpg
image2.jpg
items/
hashedfilename.json
hashedfilename.json
hashedfilename.json
Each JSON file within the items folder is named from a (lower case) MD5 hash of the item reference. The contents of each item file will be something like:
{
"reference": "",
"content": "",
"workflow": null,
"metadata": {
"acknowledgements": null,
"scoring_type": "per-question"
},
"tags": {},
"questions": [],
"features": []
}
Supported Question Types - Learnosity to QTI
The following Learnosity question types are supported:
Known limitations
General
You cannot use <u>
elements in QTI 2.1. We suggest using a <span>
with a CSS classname instead.
All template
fields must be wrapped in a block element.
Cloze Association
Cannot use the group possible responses option.
Help
Remember you can ask for help
:
$ mo convert:to:qti --help
Usage:
convert:to:qti [options]
Options:
-i, --input=INPUT The input path to your Learnosity content [default: "./data/input"]
-o, --output=OUTPUT An output path where the QTI will be saved [default: "./data/output"]
-f, --format=FORMAT A flag to choose how to format the QTI output content package, from a list of supported formats.
This option supports the following possible values: (canvas, qti). Pass the canvas option to export
QTI content that is compatible with Canvas LMS. The default is qti, which outputs non LMS-specific QTI.
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Help:
Converts Learnosity JSON to QTI v2.1