11/05/2014

Defining Custom Template Variables in a Building Block

The NSSE template variable b2 can be downloaded here.  My presentation from Bb DevCon 2015 can be found in that folder as well.

I would like to thank Simon Ponder of Purdue's Informatics group for sharing his code on which I based the below upon.  Hopefully, this post will give others looking to create their own custom template variables in Blackboard Learn enough information to get started.

To start off, we have to define our plugin as a java extension in the bb-manifest.xml file like so:

<?xml version="1.0" encoding="utf-8"?>
<plugin>

    <name value="bsTemplateVar" />
    <handle value="bs-template-var" />
    <description value="Brett's Custom Template Variable" />
    <default-locale value="en_US" />
 <webapp-type value="javaext"/>
...
</plugin>

We'll then have to define the extension:

<extension-defs>
   <definition namespace="blackboard.platform">
   <extension id="customContextHandler" point="blackboard.platform.contextHandler" class="edu.bstemplatevar.CustomContextHandler" singleton="false" />
   </definition>  
</extension-defs>

Here "edu.miami.bstemplatevar.CustomContextHandler" is the fully qualified name of the context handler class that will point to the custom template variable resolver class. in this case, the package name is edu.miami.bstemplatevar and the class name is CustomContextHandler.

Here is the contents of CustomContextHanlder.java:

package edu.bstemplatevar;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import blackboard.data.course.Course;
import blackboard.persist.BbPersistenceManager;
import blackboard.platform.context.Context;
import blackboard.platform.context.ContextEntry;
import blackboard.platform.context.ContextHandler;
import blackboard.platform.security.EntitlementList;
import blackboard.platform.security.Entitlements;
import blackboard.platform.security.SecurityContext;
import blackboard.util.resolver.Resolver;

public class CustomContextHandler implements ContextHandler {
 
 public CustomContextHandler() {

 }

 public Entitlements getEffectiveEntitlements(Context ctx) {
  return new EntitlementList();
 }

 public Entitlements getRestrictedEntitlements(Context ctx) {
  return null;
 }

 public List getSecurityContexts(Context unused) {
  return new ArrayList();
 }

 public List resolveKeys(HttpServletRequest request,
   BbPersistenceManager unused) {
  CustomResolver resolver = new CustomResolver(request);
  Resolver.attachResolverToContext(resolver);
  return new LinkedList();
 }
 
}


Below is the CustomResolver class:

package edu.bstemplatevar;

import javax.servlet.http.HttpServletRequest;

import blackboard.platform.context.Context;
import blackboard.platform.context.ContextManagerFactory;
import blackboard.util.resolver.ResolverComponent;

/**
 * This handles a custom template variable that uses deferred expansion, to
 * give run-time results of the current user. Template variables are in the
 * following form: '@X@template.variable@X@'
 */
public class CustomResolver implements ResolverComponent {

 private static HttpServletRequest _request = null;

 public CustomResolver(HttpServletRequest request) {
  _request = request;
 }

 public String[] getKeys() {

  return (new String[] {"bs_user"}); // the first part of the template variable (@X@ tag) - bs_user in @X@bs_user.testvar@X@
 }

 public String resolve(String method, String attributes[]) {
  String varout;
  

  if ("testvar".equalsIgnoreCase(method)) { //the second part of the @X@ tag - testvar in @X@umia_user.testvar@X@
   
   try {
    Context ctx = ContextManagerFactory.getInstance().getContext();
    ContextManagerFactory.getInstance().setContext(_request);
    
    varout = "user id: " + ctx.getUser().getUserName() + "  user batch_uid: " + ctx.getUser().getBatchUid();

    return varout;

   } catch (Exception e) {

   } finally {
    ContextManagerFactory.getInstance().releaseContext();
   }

  }
  
  if ("another".equalsIgnoreCase(method)) { // @X@bs_user.another@X@
   
   try {
    Context ctx = ContextManagerFactory.getInstance().getContext();
    ContextManagerFactory.getInstance().setContext(_request);

    varout = "another template variable defined";

    return varout;

   } catch (Exception e) {

   } finally {
    ContextManagerFactory.getInstance().releaseContext();
   }

  }
  return null;
 }
 
}


Of course, you can have whatever logic you want in there to actually define what is returned by this class, but as you can see, you are not limited to only one custom template variable per class.
A compile ready copy of this example code can be found here. This is a gradle project based on the basic b2 template, so "gradlew war" will build the war file in the build\libs directory.

3 comments:

  1. I'm interested in this since we are getting a request to do the same thing but I was not able to access to two files that you mentioned here.

    Can you share them with me?

    Thanks

    ReplyDelete
    Replies
    1. Shannon: Did you get a reply on your request for the files? I would also like to have the files. Thank you! George

      Delete
  2. I am really enjoying reading your well written articles. It looks like you spend a lot of effort and time on your blog. I have bookmarked it and I am looking forward to reading new articles. Keep up the good work. holmes blackboard

    ReplyDelete