Skip to content
Martin van Velsen edited this page Feb 24, 2020 · 28 revisions

Some useful help:

We've tried to make this guide as easy to use as possible with lots of examples to go with the explanations. For a listing of all examples and files please take a look at the repository:

Table of Contents

  1. Upfront Information
    1. The OLI Content Package
    2. The OLI Workbook Page
    3. The Activity Files
  2. Step by Step Example of a fragment Activity
  3. Step by Step Example of an IFrame Activity
  4. Adding Logging
  5. API
    1. Bootstrap API
    2. Resource Management Calls
    3. Basic Logging Calls
    4. DataShop Logging Calls
  6. Example Applications
  7. Useful Links

Upfront Information

To get started creating a new embedded activity (also sometimes called a custom activity) you will need to things: knowledge as to how OLI loads and manages learning content and our client-side JavaScript API. We'll discuss each in turn and we will do it in more or less as a recipe so that you can read through this document and end up with the learning activity you want.

The OLI Content Package

To get started we will have to explain how your activity is situated within the broader structure of an OLI content package. A content package is what the OLI course builder uses to create and deploy a new course. It is a folder that holds all the files and information needed to build a full course.

Most content developers will be using an authoring environment to create this content package and reserve space where custom activities will be placed later. Your task is to obtain the content package folder and insert the activity files in the correct places and make the appropriate links in workbook pages.

Workbook pages are what OLI is all about. A workbook page is one single page of HTML learning content. Currently all content comes in the form of XML and for every workbook page that appears in your course there will be a corresponding workbook page in your content package.

For your convenience we've included three example content packages in the repository:

Each of these, if deployed, will create a complete course in OLI. They are fully configured to use all the features of embedded activities and we will use them as the basis for all the examples below.

If you were to unzip the first package, then you should see a structure that looks very much like the one below:

Content Package Layout

This is the standard layout of a content package.

Once you've created all the XML files and linked them up you are ready to test and deploy your content. We encourage you to contact us to get accounts on one of our development servers so you can try out the entire process of development, deploy and test. All in all you will be following the process workflow shown below:

Development Process

The OLI Workbook Page

As an activity developer you will be custom fitting your applications into what OLI calls workbook pages. Each workbook page represents a digital learning content page. You can intersperse one or more custom activities into a page. When OLI loads a page, it will retrieve the page XML from disk, transform it into HTML through the use of XSLT and then send it to the browser. The browser loads the page and loads all the activities embedded in the page one by one.

Typically you will want to classify your activity as one of the purpose types available in OLI. In our examples in this documentation we use the Learn-by-Doing purpose type, configured by adding: purpose="learnbydoing" to your activity XML definition. More on that below.

All in all your workbook page with added custom activity will look something like this:

Development Process

Before we go into the details of a full example, let's first start with an almost empty workbook page. This might look something like this in XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE workbook_page PUBLIC "-//Carnegie Mellon University//DTD Workbook Page 3.8//EN" "http://oli.web.cmu.edu/dtd/oli_workbook_page_3_8.dtd">
<?xml-stylesheet type="text/css" href="http://oli.web.cmu.edu/authoring/oxy-author/oli_workbook_page_3_7.css"?>
<workbook_page id="example_workbook">
    <head>
        <title>Test 03 - Workbook Page Tests (Blank)</title>
    </head>
    <body>
        <section>
            <title>Empty Section</title>
            <body>
                <p>Body goes here</p>
            </body>
        </section>
    </body>
</workbook_page>

When added to a content package and deployed on the server it will render a very basic content page. In fact it gives you a rather dreary looking content page and also doesn't contain the custom code we want to run. In fact if you were to view this in OLI then it would look much like the screenshot below:

Development Process

Let's take a look at what we need to do to replace the body text with a link to our application code. Take a look at the XML below, it shows the exact same workbook page XML but instead of text it now defines what OLI calls an activity. This activity is of type "Learn by Doing" and points to an activity called "example".

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE workbook_page PUBLIC "-//Carnegie Mellon University//DTD Workbook Page 3.8//EN" "http://oli.web.cmu.edu/dtd/oli_workbook_page_3_8.dtd">
<?xml-stylesheet type="text/css" href="http://oli.web.cmu.edu/authoring/oxy-author/oli_workbook_page_3_7.css"?>
<workbook_page id="example_workbook">
    <head>
        <title>Test 02a - Embedded Activities</title>
    </head>
    <body>
        <section>
            <title>Test 02a - Embedded Activities</title>
            <body>
                <wb:inline idref="example" purpose="learnbydoing" />
            </body>
        </section>
    </body>
</workbook_page>

The Activity Files

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE embed_activity PUBLIC "-//Carnegie Mellon University//DTD Embed 1.1//EN" "http://oli.cmu.edu/dtd/oli-embed-activity_1.0.dtd">
<embed_activity id="example" width="670" height="700" >
    <title>Test 02b, Embedded Activities - (API Test)</title>
    <source>webcontent/api/oli.js</source>
    <assets>	
        <asset name="style">examples/webcontent/example.css</asset>
        <asset name="javascript">examples/webcontent/example.js</asset>
        <asset name="layout">examples/webcontent/example.html</asset>		
    </assets>
</embed_activity>

Step by Step Example of a fragment Activity

function startActivity() {
  // Turn on massive amounts of console output
  useDebugging=true;
  
  $("#container").text ("The activity is loaded and ready to go.");

  // From this point on you have access to the global object: APIActivity
  // Use that object to gain access to OLI and logging functionality 
}

Step by Step Example of an IFrame Activity

Adding Logging

Ultimately the effectiveness of your custom activity can only be determined by looking at student interaction data. You're partly responsible for generating this data, although we provide a lot of convenient API methods to accomplish this. For more details, see the Logging page.

API

Most of what you get when you use the OLI embedded activity framework is an API that allows you to operate within an information rich environment. The API allows you to obtain information about the student using your activity, but it also provides a means to log data in such a way that existing data analytics systems can easily generate reports and analyses.

Before you can start using the API you need to obtain a pointer to the API object. If you've created a fragment based activity then you can simply make calls directly on APIActivity. If you're running your activity in an IFrame then you will need to access it through window.parent.APIActivity.

Bootstrap API

  • startActivity ()
    • Arguments:
      • None
    • Returns:
      • None
    • Description: Create a global function with this name, to be called by the framework when all resources have been processed and loaded. Waiting for this function to be called ensures that your activity page will be booted with all resources loaded in the proper order.

Resource Management Calls

  • findResourceByExtension (anExtension)

    • Arguments:
      • newX - <Integer> X coordinate.
      • newY - <Integer> Y coordinate.
    • Returns:
      • None
    • Description:
  • findResourcesByExtension (anExtension)

    • Arguments:
      • newX - <Integer> X coordinate.
      • newY - <Integer> Y coordinate.
    • Returns:
      • None
    • Description:
  • findResourceByType (aType)

    • Arguments:
      • newX - <Integer> X coordinate.
      • newY - <Integer> Y coordinate.
    • Returns:
      • None
    • Description:
  • findResourcesByType(aType)

    • Arguments:
      • newX - <Integer> X coordinate.
      • newY - <Integer> Y coordinate.
    • Returns:
      • None
    • Description:
  • getScript(aURL, aPath, aCallback)

    • Arguments:
      • newX - <Integer> X coordinate.
      • newY - <Integer> Y coordinate.
    • Returns:
      • None
    • Description:
  • getFile (aURL,aPath,aCallback)

    • Arguments:
      • newX - <Integer> X coordinate.
      • newY - <Integer> Y coordinate.
    • Returns:
      • None
    • Description:

Basic Logging Calls

  • logNavigation (qId,aRoute)

    • Arguments:
      • newX - <Integer> X coordinate.
      • newY - <Integer> Y coordinate.
    • Returns:
      • None
    • Description:
  • logProblemComplete (qId)

    • Arguments:
      • newX - <Integer> X coordinate.
      • newY - <Integer> Y coordinate.
    • Returns:
      • None
    • Description:
  • logCorrect (qId, aDataBlock)

    • Arguments:
      • newX - <Integer> X coordinate.
      • newY - <Integer> Y coordinate.
    • Returns:
      • None
    • Description:
  • logInCorrect (qId, aDataBlock)

    • Arguments:
      • newX - <Integer> X coordinate.
      • newY - <Integer> Y coordinate.
    • Returns:
      • None
    • Description:
  • logCorrectStep (qId, aStepId, aDataBlock)

    • Arguments:
      • newX - <Integer> X coordinate.
      • newY - <Integer> Y coordinate.
    • Returns:
      • None
    • Description:
  • logInCorrectStep (qId, aStepId, aDataBlock)

    • Arguments:
      • newX - <Integer> X coordinate.
      • newY - <Integer> Y coordinate.
    • Returns:
      • None
    • Description:
  • logHint (qId, aFeedback)

    • Arguments:
      • newX - <Integer> X coordinate.
      • newY - <Integer> Y coordinate.
    • Returns:
      • None
    • Description:

DataShop Logging Calls

Example Applications

Useful Links