Commit b065f7f8 by spearce

Draft of LTI documentation

First attempt at writing LTI documentation. Several questions for tech
reviewers.
parent b99f991f
...@@ -17,10 +17,10 @@ templates for these problems, but the problems open directly in the ...@@ -17,10 +17,10 @@ templates for these problems, but the problems open directly in the
create. These problems can be any type. create. These problems can be any type.
- :ref:`Drag and Drop` Drag and drop problems require students to drag text - :ref:`Drag and Drop` Drag and drop problems require students to drag text
or objects to a specific location on an image. or objects to a specific location on an image.
- :ref:`JavaScript Input` JavaScript input problems allow you to incorporate
problem types that you've created in HTML into Studio via an IFrame.
- :ref:`Image Mapped Input` Image mapped input problems require students to - :ref:`Image Mapped Input` Image mapped input problems require students to
click a specific location on an image. click a specific location on an image.
- :ref:`JavaScript Input` JavaScript input problems allow you to incorporate
problem types that you've created in HTML into Studio via an IFrame.
- :ref:`Math Expression Input` Math expression input problems require - :ref:`Math Expression Input` Math expression input problems require
students to enter a mathematical expression as text, such as students to enter a mathematical expression as text, such as
e=m\*c^2. e=m\*c^2.
...@@ -136,6 +136,120 @@ To create a image mapped input problem: ...@@ -136,6 +136,120 @@ To create a image mapped input problem:
#. In the component editor, replace the example code with your own code. #. In the component editor, replace the example code with your own code.
#. Click **Save**. #. Click **Save**.
.. _JavaScript Input:
JavaScript Input
----------------
The JavaScript Input problem type allows you to create your own learning tool
using HTML and other standard Internet languages and then add the tool directly
into Studio. When you use this problem type, Studio embeds your tool in an
IFrame so that your students can interact with it in the LMS. You can grade
your students' work using JavaScript and some basic Python, and the grading
is integrated into the edX grading system.
This problem type doesn't appear in the menu of advanced problems in Studio. To
create a JavaScript input problem type, you'll create a blank advanced problem,
and then enter your code into the component editor.
.. image:: /Images/JavaScriptInputExample.gif
Create a JavaScript Input Problem
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#. Create your JavaScript application, and then upload all files associated with
that application to the **Files & Uploads** page.
#. In the unit where you want to create the problem, click **Problem**
under **Add New Component**, and then click the **Advanced** tab.
#. Click **Blank Advanced Problem**.
#. In the component that appears, click **Edit**.
#. Click the **Settings** tab.
#. Set **Maximum Attempts** to a number larger than zero.
#. In the component editor, enter your code.
#. Click **Save**.
To re-create the example problem above, follow these steps.
#. Go to :ref:`Appendix F` and use the code samples to create the following files:
- webGLDemo.html
- webGLDemo.js
- webGLDemo.css
- three.min.js
#. On the **Files & Uploads** page, upload the four files you just created.
#. Create a new blank advanced problem component.
#. On the **Settings** tab, set **Maximum Attempts** to a number larger than
zero.
#. In the problem component editor, paste the code below.
#. Click **Save.**
JavaScript Input Problem Code
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
<problem display_name="webGLDemo">
In the image below, click the cone.
<script type="loncapa/python">
import json
def vglcfn(e, ans):
'''
par is a dictionary containing two keys, "answer" and "state"
The value of answer is the JSON string returned by getGrade
The value of state is the JSON string returned by getState
'''
par = json.loads(ans)
# We can use either the value of the answer key to grade
answer = json.loads(par["answer"])
return answer["cylinder"] and not answer["cube"]
# Or we can use the value of the state key
'''
state = json.loads(par["state"])
selectedObjects = state["selectedObjects"]
return selectedObjects["cylinder"] and not selectedObjects["cube"]
'''
</script>
<customresponse cfn="vglcfn">
<jsinput
gradefn="WebGLDemo.getGrade"
get_statefn="WebGLDemo.getState"
set_statefn="WebGLDemo.setState"
width="400"
height="400"
html_file="/static/webGLDemo.html"
/>
</customresponse>
</problem>
.. notes:: When you create a JavaScript Input problem, keep the following in mind.
- The webGLDemo.js file defines the three JavaScript functions (**WebGLDemo.getGrade**,
**WebGLDemo.getState**, and **WebGLDemo.setState**).
- The JavaScript input problem code uses **WebGLDemo.getGrade**, **WebGLDemo.getState**,
and **WebGLDemo.setState** to grade, save, or restore a problem. These functions must
be global in scope.
- **WebGLDemo.getState** and **WebGLDemo.setState** are optional. You only have to define
these functions if you want to conserve the state of the problem.
- **Width** and **height** represent the dimensions of the IFrame that holds the
application.
- When the problem opens, the cone and the cube are both blue, or "unselected." When
you click either shape once, the shape becomes yellow, or "selected." To unselect
the shape, click it again. Continue clicking the shape to select and unselect it.
- The response is graded as correct if the cone is selected (yellow) when the user
clicks **Check**.
- Clicking **Check** or **Save** registers the problem's current state.
.. _Math Expression Input: .. _Math Expression Input:
Math Expression Input Math Expression Input
......
...@@ -30,8 +30,8 @@ See the following topics: ...@@ -30,8 +30,8 @@ See the following topics:
Create an HTML Component Create an HTML Component
***************************** *****************************
To create a new HTML component in an existing Unit, ensure the Unit is Private. To create a new HTML component in an existing unit, ensure the unit is private.
For more information on Public and Private Units, see :ref:`Public and Private Units`. For more information on public and private units, see :ref:`Public and Private Units`.
#. Under **Add New Component**, click the **html** icon. #. Under **Add New Component**, click the **html** icon.
......
********************** .. _Working with LTI Components:
Create a LTI Component
**********************
Description Working with LTI Components
=========== ============================
The LTI XModule is based on the `IMS Global Learning Tools Interoperability <http://www.imsglobal.org/LTI/v1p1p1/ltiIMGv1p1p1.html>`_ Version 1.1.1 specifications. Overview
---------
Enabling LTI You may have a digital copy of your textbook that uses a format other than PDF. If so, you
============ can add that textbook to Studio by using a Learning Tools Interoperability (LTI) XModule (**SP: OK
to say "component" instead of "XModule"? Our docs haven't talked about
XModules yet, so users may not know what they are.**).
The LTI XModule is based on the
`IMS Global Learning Tools Interoperability <http://www.imsglobal.org/LTI/v1p1p1/ltiIMGv1p1p1.html>`_
version 1.1.1 specifications.
It is not available from the list of general components. To turn it on, add You can use an LTI component in two ways.
"lti" to the "advanced_modules" key on the Advanced Settings page.
The module supports 2 modes of operation. - You can show external LTI content. This content is displayed only.
- You can show LTI content that will be graded by an external provider.
1. Simple display of external LTI content Before you create an LTI component from an external LTI provider in a unit, you must
2. Display of LTI content that will be graded by external provider have the following information so that you can register that provider.
In both cases, before an LTI component from an external provider can be - The **LTI ID**. This value is an internal string that specifies the external LTI
included in a unit, the following pieces of information must be known/decided provider that you want to add to the course. (**SP: How does the user obtain this ID?
upon: Does it have to be a certain length?**)
**LTI id** [string] The LTI ID can contain uppercase and lowercase alphanumeric characters,
Internal string representing the external LTI provider. Can contain multi- as well as underscore characters (_). For example, your LTI ID may be (**SP: Need
case alphanumeric characters, and underscore. example**).
**Client key** [string] - The **client key**. This value is a string that is used for OAuth authentication.
Used for OAuth authentication. Issued by external LTI provider. You can obtain this value from the external LTI provider. (**SP: What is OAuth
authentication? Do end users need to know what it is, or can we just say "that
Studio uses to verify that the LTI provider is safe" [or similar]? Does the key have to
have a specific number of characters? Are all types of characters allowed?**) For
example, your client key may be (**SP: Need example**).
**Client secret** [string] - The **client secret**. This value is a string that is used for OAuth authentication.
Used for OAuth authentication. Issued by external LTI provider. You can obtain this value from the external LTI provider. (**Does the key have to
have a specific number of characters? Are all types of characters allowed?** For
example, your client key may be (**SP: Need example**).
LTI id is necessary to differentiate between multiple available external LTI
providers that are added to an edX course.
The three fields above must be entered in "lti_passports" field in the format:: Create an LTI Component
-----------------------
Creating an LTI component in your course has three steps.
#. Add LTI to the **advanced_modules** policy key.
#. Register the LTI provider.
#. Create the LTI component in an individual unit.
Add LTI to the Advanced Modules Policy Key
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#. On the **Settings** menu, click **Advanced Settings**.
#. On the **Advanced Settings** page, locate the **Manual Policy
Definition** section, and then locate the **advanced_modules**
policy key (this key is at the top of the list).
.. image:: Images/AdvancedModulesEmpty.gif
#. Under **Policy Value**, place your cursor between the brackets, and
then enter **"lti"**. Make sure to include the quotation marks,
but not the period.
.. image:: Images/LTI_Policy_Key.gif
**Note** *If the **Policy Value** field already contains text, place your cursor directly after the
closing quotation mark for the final item, and then enter a comma followed by **"lti"** (make sure that you
include the quotation marks).*
#. At the bottom of the page, click **Save Changes**.
The page refreshes automatically. At the top of the page, you see a
notification that your changes have been saved.
Register the External LTI Provider
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To regiser the external LTI provider, you'll add the LIT ID, the client key, and
the client secret in the **lti_passports** policy key.
#. On the **Advanced Settings** page, locate the **lti_passports**
policy key.
#. Under **Policy Value**, place your cursor between the brackets, and
then enter the LTI ID, client key, and client secret in the following format.
[
"{lti_id}:{client_key}:{client_secret}" "{lti_id}:{client_key}:{client_secret}"
]
Multiple external LTI providers are separated by commas:: For example, the value in the lti_passports field may be the following.
"(**SP: Need an example.**)"
If you have multiple LTI providers, separate the values with a comma.
::
[
"{lti_id_1}:{client_key_1}:{client_secret_1}", "{lti_id_1}:{client_key_1}:{client_secret_1}",
"{lti_id_2}:{client_key_2}:{client_secret_2}", "{lti_id_2}:{client_key_2}:{client_secret_2}",
"{lti_id_3}:{client_key_3}:{client_secret_3}" "{lti_id_3}:{client_key_3}:{client_secret_3}"
]
Adding LTI to a unit #. At the bottom of the page, click **Save Changes**.
====================
The page refreshes automatically. At the top of the page, you see a
notification that your changes have been saved.
After LTI has been enabled, and an external provider has been registered, an Add the LTI Component to a Unit
instance of it can be added to a unit. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LTI will be available from the Advanced Component category. After adding an LTI #. In the unit where you want to create the problem, click **Advanced**
component to a unit, it can be configured by Editing it's settings (the Edit under **Add New Component**.
dialog). The following settings are available: #. In the list of problem types, click **LTI**.
#. In the component that appears, click **Edit**.
#. In the component editor, set the options that you want.
#. Click **Save**.
**Display Name** [string] (**SP: It would be great to clean up the text of the UI for this component. I'm happy
Title of the new LTI component instance to suggest text.**)
**custom_parameters** [string] .. list-table::
With the "+ Add" button, multiple custom parameters can be :widths: 10 80
:header-rows: 1
* - **Display Name**
- Specifies the name of the problem.
* - **custom_parameters** [string]
- With the "+ Add" button, multiple custom parameters can be
added. Basically, each individual external LTI provider can have a separate added. Basically, each individual external LTI provider can have a separate
format custom parameters. For example:: format custom parameters. For example::
key=value key=value
**graded** [boolean] (**SP: I'm not clear on what these are. What would a custom parameter be used for?
Whether or not the grade for this particular LTI instance problem will be Can we provide a specific example?**)
counted towards student's total grade.
* - **graded**
- Indicates whether the grade for the problem counts towards student's total grade. By
default, this value is set to **False**.
**launch_url** [string] * - **has_score**
If `rgaded` above is set to `true`, then this must be - Specifies whether the problem has a numerical score. By default, this value
the URL that will be passed to the external LTI provider for it to respond with is set to **False**.
a grade.
**lti_id** [string] * - **launch_url**
Internal string representing the external LTI provider that - Lists the URL that Studio sends to the external LTI provider so that the provider
will be used to display content. The same as was entered on the Advanced can send back students' grades. This setting is only used if **graded** is set to
Settings page. **True**.
**open_in_a_new_page** [boolean] * - **lti_id**
If set to `true`, a link will be present for the student - Specifies the LTI ID for the external LTI provider. This value must be one of the
to click. When the link is clicked, a new window will open with the external LTI IDs that you entered on the **Advanced Settings** page.
LTI content. If set to `false`, the external LTI content will be loaded in the
page in an iframe.
**weight** [float] * - **open_in_a_new_page** [boolean]
If the problem will be graded by an external LTI provider, - Indicates whether the problem opens in a new page. If you set this value to True,
the student clicks a link that opens the LTI content in a new window. If you set
this value to False, the LTI content opens in an IFrame in the current page.
* - **weight** [float]
- If the problem will be graded by an external LTI provider,
the raw grade will be in the range [0.0, 1.0]. In order to change this range, the raw grade will be in the range [0.0, 1.0]. In order to change this range,
set the `weight`. The grade that will be stored is calculated by the formula:: set the `weight`. The grade that will be stored is calculated by the formula:
stored_grade = raw_grade * weight stored_grade = raw_grade * weight
(**SP: Raw grade means points earned?**)
...@@ -20,6 +20,7 @@ unit. ...@@ -20,6 +20,7 @@ unit.
- :ref:`Word Cloud` Word cloud problems show a colorful graphic of the - :ref:`Word Cloud` Word cloud problems show a colorful graphic of the
words that students enter as responses to a prompt. words that students enter as responses to a prompt.
.. _ Add Advanced Component:
**Add the Advanced Component to Your Course** **Add the Advanced Component to Your Course**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment