© Blackboard, Inc. All rights reserved. My First Building Block as a Content Type Heather Natour...

Post on 26-Dec-2015

215 views 0 download

Tags:

Transcript of © Blackboard, Inc. All rights reserved. My First Building Block as a Content Type Heather Natour...

© Blackboard, Inc. All rights reserved.

My First Building Block as a Content Type

Heather NatourSenior Lead EngineerBlackboard Inc.

July 18th 1:30pm

Overview

» Types of Content Oriented Building Block Integrations

» Look at Various Implementations» Tips and Tricks» Questions

Types of Integrations

» Content-Handlers which work with internal data structures and use Building Block perisisters for data storage

» Content-Handlers which work with internal data structures and use other means for storage (XML, Java Property Files, etc)

» Content-Handlers which simply link to an external system

Before we look at differences…

» Let’s examine the commonalities….

» Let’s quickly walk through our Building Block Planning Process (From the My First Building Block Presentation)

»

Planning

» Where are you going to hook your application into Blackboard?

User Interface Integration

• Content-Handlers appear under the “add other” pull down from the content areas.

Planning

» Which APIs are you going to use?

API Capabilities» Building Blocks API

» Announcement (read and write)» Calendar (read and write)» Content (read and write)» Gradebook (read and write)» Session (read and write)» File system (read and write)» *User (read)» *Course (read)» *Membership (read)

Structure of the Building Block

» It’s a standard JAVA Web Application (Webapp) with some additional descriptive data (XML Files) that is used by Blackboard to manage registration, deployment, security, and management.

Directory Structure

Package Format

» A webapp is a zip file with a specific directory structure

» WinZip, PkZip, or Java’s Jar utility will all create the correct package

» Even though it is a zip file, the extension does not matter (.zip, .war, .bb will all work)

WEB-INF

» Hidden from web» Contents

» web.xml» bb-manifest.xml» Config directory» Classes directory» Lib directory

Config Directory

» Hidden from web» Only directory that is owned by your

building block» Can contain anything» No size limit

Custom Code and Libraries

» Classes» Stored in WEB-INF\classes

» Jars» Stored in WEB-INF\lib» Automatically on classpath via custom

classloader

Manifest Structure» Bb-manifest.xml

» Set of directives the developer provides» Building Blocks Configuration» Application Definitions

» Content Handlers

» UI Links

» Portal Modules

» Security Declarations» Let’s Take a Look at one for content …

Bb-manifest.xml» <?xml version="1.0" encoding="ISO-8859-1"?>

» <manifest>

» <plugin>

» <name value= "Sample Content Handler"/>

» <handle value= "sample-contenthandler"/>

» <description value= "Sample Content Handler"/>

» <version value= "1.0.0"/>

» <requires>

» <bbversion value="6.0.0"/>

» </requires>

» <vendor>

» <id value="bb"/>

» <name value="Blackboard Research and Development"/>

» <url value="http://www.blackboard.com/" />

» <description value="Blackboard Research and Development Team" />

» </vendor>

» <http-actions>

» <config value="admin/config.jsp"/>

» <remove value="admin/remove.jsp"/>

» </http-actions>

Bb-manifest.xml

» ...

» <content-handlers>

» <content-handler>

» <name value=“Sample Content Handler"/>

» <handle value= "resource/x-bb-samplecontent"/>

» <http-actions>

» <create value="ch1/create.jsp"/>

» <modify value="ch1/modify.jsp"/>

» <remove value="ch1/remove.jsp"/>

» </http-actions>

» <icons>

» <toolbar value="/images/add_ch1.gif"/>

» <listitem value="/images/icon.gif"/>

» </icons>

» </content-handler>

» </content-handlers>

» ...

Set Handler

Set Create, Modify, and

Remove handlers

Bb-manifest.xml

» ...» <permissions> » <permission type="persist" name="Content" actions="create,modify,delete"/>

» <permission type="attribute" name="user.personalinfo" actions="get"/> » <permission type="attribute" name="user.authinfo" actions="get"/>» </permissions>

» </plugin>» </manifest>

Now we know the structure…

» Once we have decided our directory layout and created (customized) our bb-manifest.xml file, we are ready to look at the JSP pages which comprise our webapp.

With that…

» We need to setup a structure for our webapp

Deploy the skeleton

» It’s far easier to deploy the skeleton webapp and then make your changes directly on your DEVELOPMENT server.

» Files are located inblackboard/content/ci/bb_bb60/xxx-xxxx/webapp

»

Some good things to know…

» Course ID and Container ID are passed to pages

» If you use the taglibs (BbUI and BbData) you will always have access to the session data, user data, consistent UI widgets, etc.

» You have access to read/write files to your webapps config space» Good for configuration data or

application data!

Create.jsp» <%

» ///////////////////////////////////////////////////////////

» // Filename: Create.jsp

» // Desc: Part of the sample content-handler, this file

» // is responsible for displaying the form to gather

» // the data for the creation of the content object.

» ///////////////////////////////////////////////////////////

» %>

» <%@ page import="

» blackboard.platform.*,

» blackboard.platform.plugin.*"

» errorPage="/error.jsp"

» %>

» <%@ taglib uri="/bbUI" prefix="bbUI"%>

» <%@ taglib uri="/bbData" prefix="bbData"%>

» <bbData:context id="ctx">

Page Imports

Import Tag Libs

Establish Context

Create.jsp» <%

» if (!PlugInUtil.authorizeForCourseControlPanel(request, response))

» return;

» %>

» <bbUI:docTemplate title="Create Sample Content">

» <bbUI:coursePage courseId="<%=PlugInUtil.getCourseId(request)%>">

» <form action="create_proc.jsp" method='post' NAME='the_form' ID='the_form'>

» <input type="hidden" name="course_id" value="<%=request.getParameter("course_id")%>">

» <input type="hidden" name="parent_id" value="<%=request.getParameter("content_id")%>">

» <bbUI:breadcrumbBar handle="control_panel" isContent="true">

» <bbUI:breadcrumb> SAMPLE CONTENT HANDLER</bbUI:breadcrumb>

» </bbUI:breadcrumbBar>

Check for Auth

Doc and Course Taglibs

Course and Content IDs are

passed in

Breadcrumb

Create.jsp

» <bbUI:step title="Content Information" number="1">

» <bbUI:dataElement label="Title">

» <input type="text" name="title" size='50'>

» </bbUI:dataElement>

» <bbUI:dataElement label="Description">

» <TEXTAREA COLS="50" ROWS="15“ NAME="maindata"> </TEXTAREA>

» </bbUI:dataElement>

» </bbUI:step>

» <bbUI:step title="Options" number="2">

» <bbUI:dataElement label="Do you want to make the content visible"><FONT size="2" face="Arial, Helvetica, sans-serif"><input type="Radio" name="isAvailable" value="true" checked>Yes <input type="Radio" name="isAvailable" value="false">No </bbUI:dataElement>

» <bbUI:dataElement label="Do you want to track number of views"><FONT size="2" face="Arial, Helvetica, sans-serif"><input type="Radio" name="isTrack" value="true" >Yes <input type="Radio" name="isTrack" value="false" checked>No </bbUI:dataElement>

» <bbUI:dataElement label="Do you want to add Metadata?"><FONT size="2" face="Arial, Helvetica, sans-serif"><input type="Radio" name="isDescribe" value="true" >Yes <input type="Radio" name="isDescribe" value="false" checked>No </bbUI:dataElement>

» </bbUI:step>

Create.jspCreate.jsp

Create.jsp

» » <bbUI:stepSubmit title="Submit" number="3" />

» </bbUI:coursePage> » </bbUI:docTemplate>

» </bbData:context>

Create.jsp

Create_proc.jsp» Just the Highlights!

» // retrieve the Db persistence manager from the persistence service

» BbPersistenceManager bbPm = BbServiceManager.getPersistenceService().getDbPersistenceManager();

» // generate the internal IDs for the course and parent

» Id courseId = bbPm.generateId(Course.COURSE_DATA_TYPE,request.getParameter("course_id"));

» Id parentId = bbPm.generateId(CourseDocument.COURSE_DOCUMENT_DATA_TYPE,request.getParameter("parent_id"));

» // create a new content iteam

» Content courseDoc = new Content();

» //set the title

» courseDoc.setTitle(request.getParameter("title"));

Create_proc.jsp » // set the main data (as HTML data)» String strMainData = request.getParameter("maindata");» FormattedText text = new FormattedText(strMainData,FormattedText.Type.HTML);» courseDoc.setBody( text );

» // set the parent ID» courseDoc.setParentId(parentId);» » // set the content handler » courseDoc.setContentHandler( "resource/x-bb-samplecontent" );

» // set the course ID» courseDoc.setCourseId( courseId );

» // Set to Track the content or not» String strTracked = request.getParameter("isTrack");» if (strTracked.equalsIgnoreCase("true")) {» courseDoc.setIsTracked(true);» } else {» courseDoc.setIsTracked(false);» }

Create_proc.jsp

» // validate the new content idem» courseDoc.validate();

» // Persist the object» ContentDbPersister contentPersister = (ContentDbPersister)

bbPm.getPersister( ContentDbPersister.TYPE );» contentPersister.persist( courseDoc );

Modify and Modify_proc

» Almost identical to create process.» See the sample Content Handler for details» Remove is optional clean up

Demonstration

We covered the most basic…

» Let’s touch on more advanced topics:» Storing additional parameters» Relative Referencing of the content_id» Linking to external resources» Import/Export/Copy/Migration Issues

Storing additional parameters

» What types of data do you want to store?» In what do you want to store it?

» In JAVA property files» As XML?» As Serialized Java Objects?» In your own proprietary (and somewhat

creative formats)

» Where do you store the parameters?» In the webapp’s config directory?» In the content’s directory» In the content itself (hidden)» Externally

Storing additional parametersStoring additional parameters

Using the webapps config dir» // Get the Configuration Directory

» File dir = PlugInUtil.getConfigDirectory(“bb","sample-contenthandler");

» // get the config file

» File cfg = new File(dir, “custom.properties");

» // If it doesn't exist yet, create a blank one

» if (!cfg.exists()) {

» cfg.createNewFile();

» FileOutputStream f = null;

» try {

» f = new FileOutputStream(cfg);

» } catch (FileNotFoundException e){

» out.println("Can't find the file");

» }

» Properties p = new Properties();

» // Write them out to the conf file

» p.setProperty(“name",“value");

» p.store(f,“My Configuration File");

» f.close();

» }

Using the content directory

» FileSystemService fileSysService;» fileSysService = (FileSystemService)BbServiceManager.

lookupService( FileSystemService.class );» java.io.File fileContentDirectory =

fileSysService.getContentDirectory(course, courseDocId);

» Advantages» Content on file system in this directory is

PORTABLE with import/export/copy/migration

» Can be referenced with the @X@content.url@X@ syntax rather than hard coded

Storing Data in the Content

» Why not use the content item itself and store your other data in the MAIN DATA blob?

» Use comment blocks to mask your data» Advantages: complete portability, no

external dependencies» Disadvantages: ALL Data in this field is

rendered by the content engine in the user view.

Externally» You can simply insert a URL to your own

content engine in the Blackboard content item. » Advantages:

» Many to One relationship between content and raw data

» Setup own system for management and deployment

» Disadvantages:» Content is ignorant of

copy/import/export/migration and all copies will still point to the hard coded URL

Summary

» We’ve seen how to create a new content-handler from scratch

» We’ve seen the structure of the webapp and walked through an example of one.

» We talked about the various places, structures, and methods of storing content and the advantages and disadvantages of each.

© Blackboard, Inc. All rights reserved.

Thank you!