Content_Types

Download Report

Transcript Content_Types

My First Building Block as
a Content Type
Heather Natour
Senior Lead Engineer
Blackboard Inc.
July 18th 1:30pm
© Blackboard, Inc. All rights reserved.
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
» UI
Handlers
Links
» Portal
» Security
Modules
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 in
blackboard/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
»
//
»
//
»
///////////////////////////////////////////////////////////
»
%>
»
<%@ page import="
is responsible for displaying the form to gather
the data for the creation of the content object.
»
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
Check for Auth
»
<%
»
if (!PlugInUtil.authorizeForCourseControlPanel(request, response))
»
Doc and Course
Taglibs
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">
»
»
Course and
Content IDs are
passed in
<bbUI:breadcrumb> SAMPLE CONTENT HANDLER</bbUI:breadcrumb>
</bbUI:breadcrumbBar>
Breadcrumb
Create.jsp
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, sansserif"><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, sansserif"><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.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_i
d"));
»
// 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) 
»
Storing additional parameters
»
Where do you store the parameters?
» In the webapp’s config directory?
» In the content’s directory
» In the content itself (hidden)
» Externally
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
@[email protected]@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.
»
Thank you!
© Blackboard, Inc. All rights reserved.