Adding New Content Elements

Sousa has an extensible handler system for content elements. This page documents how to add new content elements.

1. Determine the Media Type

All media element supported by Sousa must have a file extention and MIME type associated with them. Generally, standard MIME types should be used. See http://www.feedforall.com/mime-types.htm for an all in one list, or the official list at http://www.iana.org/assignments/media-types/.

1a. Resource Tool Types

In some cases, the Sakai Resource tool has already defined a media type. The following line in AddItemProducer (in the Page tool) can be enabled to see all media types going by:

System.out.println ("***** AddItemProducer - item ["+ name + "] has media type of ["+ type + "]");

This is a useful tool when trying to figure out media types. The above returns:

***** AddItemProducer - item [Nolaria.com] has media type of [text/url]

Thus we learn that the item "Nolaria.com" has a media type of "text/url".

1b. Registering the Media Type

Media types are registered in the ContentElementHandler class of the Sousa content handler package (sousa-content/util). Create a new registered type using code like this:

//	Add the URL media type.
handler = new CEUrl();
this.media.put ("text/url", handler);
this.types.add (new MediaType("text/url", "url", "URL", handler));

If several extensions or MIME types are managed by the same handler, add them.

2. Create a ContentElement Class

Create a handler class for the new content element. These classes are kept in the sousa-content/util package. Following the example above, we'll create a class called "CEUrl". This class must implement the ContentElement interface, which currently has the following methods:

public interface ContentElement {
	public String getType();
	public String getName();
	public void displayContent(UIContainer tofill, String templateId, String suffix, Item contentItem);
	public void displayThumbnail(UIContainer tofill, String templateId, Item contentItem);
	public void displayIcon(UIContainer tofill, String templateId);
	public void editParameters(UIContainer tofill, String templateIdBase, EditItem contentItem);
	public void saveParameters(EditItem item);
	public void editContent(UIContainer tofill, String templateIdBase, EditItem contentItem);
	public void saveContent(EditItem item);
	public boolean isSimple();
	public boolean isParametersEditable();
	public boolean isContentEditable();
}

2a. The displayIcon Method

If the new content element is supported by the Resource tool, it will have an icon in the Sakai reference package. The CEUrl class we are building here has an icon of "/library/image/sakai/url.gif". If the content element is custom to Sousa, then an icon needs to be created and added to both the Sequence and Page tools. If the icon is added to the webapp/cotnent/templates directory (where everything else is at this time), no path name is needed to reference the icon image from either of these tools.

These icons are 16 by 16 pixels in size, which doesn't give you a lot of room to work with:

By convention, all icons are GIF images.

2b. The displayContent Method

The displayContent() method is responsible for displaying the content associated with this element in a page layout rendering. Content is displayed by adding an RSF UIComponent to an identified tag in a template. The root of the tag is passed into displayContent, depending on the template. In the page viewer, this is "content". To this is appended a simple media type that specifies which tagged item will be used in the template. CEUrl will display a web page in an iFrame, so we will append "-framed" to the rsf:id. Finally, an optional suffix may be provided to distinguish between left and right cells in the grid layout. this is passed in as the suffix string. The code looks like this:

//	Create the template id.
String id = templateId + "-" + "framed";
if (suffix != null)
	id = id + "-" + suffix;

The UIComponent used depends on the media to be shown. Since we are going to use an iFrame to display the content, a UILink component can be used:

//	Add content to the UI container.
UILink.make(tofill, id, text.toString());

2c. The displayThumbnail Method

The displayThumbnail() method works in a manner similar to displayContent(), but what is display may different considerable. The rsf:id is created in a similar manner, but no suffix is needed so it's not passed in. In the case of CEUrl, the thumbnail will be a text display of the URL itself, so we can use the DIV tag.

Rsf:id tag creation:

String id = templateId + "-" + "text";

UIContent creation:

UIOutput.make(tofill, id, text.toString());

2d. Content Editing Methods

Editing media content falls broadly into two categories at this time: editable text and uploaded files. Future work may include custom editors for specific media types (an equations editor, for example).

Editable Text

To add an editable text field, create a prompt in the Page tool message bundle and add code similar to the following:

UIMessage.make(tofill, "edit-label", "st_plain_text_label");
String content = contentItem.getEditContent();
if ((content == null) && (contentItem.getId() != null)) {
	byte[] bytes = contentItem.getContent();
	content = new String (bytes);
}
		UIInput.make(tofill, "edit-input-textarea", "#{uploaditem.content}", content);

This field can be used to either create and edit existing text, or allow information to be cut and pasted (typically XML, though not required).

Upload File

All support for uploading of files is already present in Sousa. To indicate that this element is based on an uploaded file, create a prompt in the Page tool message bundle and force the UIInput into existence as follows:

//	Set up the file upload field.
UIMessage.make(tofill, "edit-label", "st_csv_file_label");
UIInput.make(tofill, "edit-input-file", null, "");

2e. Parameter Editing Methods

3. Register the New Content Element

Content element handlers are registered by adding code to the constructor of ContentElementHandler. To add our new CEUrl handler, we add the following code snip:

this.types.add (new MediaType("text/url", "url", "URL", handler));  // Handler in this case is the CEUrl object.

Eventually, this registration will be moved out of the constructor and into a Spring-based mechanism. This will allow anyone to write a content handler anywhere.

Once the handler is registered, that media type is recognized for all handler actions including isSupported(), displayIcon(), displayContent(), and displayThumbnail. In the future, these actions will be extended to including parameter and content editing.

4. Update the Documentation

Update the documenation as new content elements are added benefit all. It will get hard to keep track of what exists and what doesn't after a while, so make sure these pages are updated.

4a. Sousa Design Document

Update the "Supported Media Types" table in the "Extensible Media Handling" section of Sousa Design. This documentation is for developers.

4b. Sousa Learning Design Document

Update the "Content Types" in the "Content Types" section of Sousa Learning Design. This documentation is for learning designers.

4c. Sousa To Do Document

Update the "Media Objects" table in Sousa To Do. This documentation is for Sousa project leaders.

5. Testing

The following tests should be run to make sure that the new content element functions correctly in all situations.

5a. Create an Example Element

Use the Resources tool to create a sample of the new type of content element.

5b. New Content Element is Visible

In the Sousa Page tool:

  1. Edit an existing page layout object.
  2. Edit one of the tiles.
  3. Click Append.
  4. Navigate to the collection where the example content element is held.

The example element should appear with its correct name and icon.

In the Sousa Sequence tool:

  1. Edit an existing sequence.
  2. Click Append.
  3. Navigate to the collection where the example content element is held.

The example element should appear with its correct name and icon.

5c. Adding the New Content Element

In the Sousa Page tool:

  1. Edit an existing page layout object.
  2. Edit one of the tiles.
  3. Click Append.
  4. Navigate to the collection where the example content element is held.
  5. Select the example content element.

The thumbnail of the new content element should appear in the item list for that tile.

  1. Click Update to save changes to the tile.
    The content of the new content element should appear in the tile of its layout.

  1. Click Update to save changes to the layout.

In the Sousa Sequence tool:

  1. Edit an existing sequence.
  2. Click Append.
  3. Navigate to the collection where the example content element is held.
  4. Select it for append.
  5. Select the example content element.
    The thumbnail example content element should appear at the end of the sequence item list.
  6. Click Update to save changes to the sequence.

5d. View the New Content Element.

In the Sousa Page tool:

  1. Find the page layout object edited in previous tests.
  2. Select it for viewing.

The content of the new content element should appear in the tile of its layout.

In the Sousa Sequence tool:

  1. Find the sequence edited in previous tests.
  2. Select it for playing.
  3. Click Next until the last item in the sequence is reached.

The content of the new content element appears.