Skip to end of metadata
Go to start of metadata

Table of Content

LAMS has a custom tag libary, LAMS, and tools may have their own tags.

Tabbed Pages and FCK Editor Optimisations

See: Tab Controller + FCK Editor Custom Tags

Using the LAMS Tags

The code for the tags is in lams_central.jar.

In your project, add the following lines to the taglibs.xml file in the xdoclet merge directory:

<taglib>    <taglib-uri>tags-lams</taglib-uri>    <taglib-location>/WEB-INF/lams.tld</taglib-location> </taglib>

Then copy the lams.tld from lams_central/web/WEB-INF to <your project>/web/WEB-INF.

In your jsp files, include the tag library:

<%@ taglib uri="tags-lams" prefix="lams" %>



The lams:html tag should be used for all jsp pages as it sets the page direction and lang attributes on <HTML> tag.

The locale filter sets a variable in the session for the desired page direction (left to right, right to left) based on the user's locale.

It also supports the xhtml parameter sued by Struts, so if you would normally use <html:html xhtml="true">, you can use <lams:html xhtml="true"> and your web pages will have "xmlns="" as per the Struts tag and any Struts tags in the pages should behave correctly as our tag sets the Struts Globals.XHTML_KEY in the page scope.

For example, if the user's locale is en_AU then <lams:html> will become <html lang="en-AU" dir="LTR"> in the html sent to the browser. If the user's locale was ar_JO then it will be converted to <html lang="ar-JO" dir="RTL">.


The lams:head tag should be used for all jsp pages as it sets the UTF-8 encoding and pragma statements that stop the pages being cached in a browser. The caching can be an issue when LAMS is upgraded.


The User tag allows you to access the simple user details from the UserDTO object, which is stored in the shared session. It does not support the theme details properly yet - we will add them when we work out what is required.

The tag has a single paramter "property", which is the name of the property from the UserDTO to be accessed. This may be: userID, firstName, lastName, login, email or theme. Note that userID will return an Integer and theme will return a CSSThemeVisualElement. All the others will return a String.

The implementation is done using reflection so you can access any public property in the UserDTO bean. So if new properties are added, they should automatically work with the tag.

LAMS and Tool URL

Two tags are to help with printing out paths in your jsps. If you need to put in the basic LAMS url (the one defined in the configuration file e.g. http://localhost:8080/lams/) then use <lams:LAMSURL/>. If you want to put in the basic URL for your webapp (e.g. http://localhost:8080/lams/tool/lanb11/ ) then user <lams:WebAppURL/>.

All of the urls end with a "/".

If you are going to use the tags repeatedly in one page, you might think about "caching" the value, rather than having it recalculated each time.


The stylesheet needed will eventually be based on the user and user's organisation. Tools should use <lams:css/>, which will write out the user's preferred stylesheet. At present, it just refers to default.css, but this will be changed in the future to be the user's stylesheet and the default stylesheet (which is the same as aqua.css). See also LAMS Themes or Skins


<%@ page language="java" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" %> .... <c:set var="lams"><lams:LAMSURL/></c:set> <c:set var="tool"><lams:WebAppURL/></c:set>  <\!DOCTYPE HTML PUBLIC "-//W3C//DTD hTML 4.01 Transitional//EN"> <lams:html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <lams:css/>

Export portfolio pages are designed to be run offline, so for these use <lams:css localLinkPath="../"/>. The "../" indicates the path back to the "root" of the export portfolio zip file. The css files are put in the export zip file by the export portfolio core code, and the localLink option will cause the css statement to refer to the local copy.


Many of our authoring and monitoring pages include the same common javascript and css files. So there is a tag "headItems" that bundles up most of them. This tag has no parameters.


<%@ page language="java" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" %> .... <\!DOCTYPE HTML PUBLIC "-//W3C//DTD hTML 4.01 Transitional//EN"> <lams:html> <head> <headItems/>


  • Set the content type (<meta http-equiv="content-type" content="text/html; charset=UTF-8">)
  • Call the CSS tag (<lams:css />)
  • Link to the FCKEditor stylesheet (<link href="${lams}css/fckeditor_style.css" rel="stylesheet" type="text/css">)
  • Include common.js, fckeditor.js, fckcontroller.js, tabcontroller.js from lams-central
  • Include xmlrequest.js from the tool's includes/javascript folder.

Have a look at the noticeboard tool's file web/authoring/authoring.jsp to see it in use.


The Date tag produces a full date/time including timezone, using the JSTL <fmt:formatDate> to localise the date format.  The tag takes up to four parameters

  • value: Mandatory value, must be of type java.util.Date. This is the date to be shown.
  • timeago: Optional. If this is set to anything then it will produce the date in timeago format e.g. less than a minute ago, two days ago. Suggest setting it to "true" for readability but if it is set to anything it will work. When timeago is used, style and type become fairly meaningless as the raw date is only seen if there is an error with timeago.
  • style: Optional. Set to "short" if the normal date format produces a String that is too long for the screen layout
  • type: Optional. Defaults to "both". Same as the fmt:FormatDate type value.

Please the style and type parameters only in rare cases. Normally you should only supply the value parameter - this will allow us to keep our dates consistent across the system. The other parameters have only been included for rare cases when the normal format is just not suitable.

Typical example:

<lams:Date value="${}"/>

Sample outputs:
  en_AU: 1 February 2006 03:04:05 PM EST
  cy_GB: Wed Feb 01 15:04:05 EST 2006
  en_US: February 1, 2006 3:04:05 PM EST
  zh_CN: 2006?2?1? ??03?04?05? EST 

See Dates fpr the equivalent Java functions that format Dates if you need to send data via JSON.


The basic idea is replace \r\n (or \n in *nix) to <BR> tag, so it can display break line normally.

It is 100% compatible with STRUT HTML textarea tag. The content saved into database thru this tag is compatible with FCKedit as well, which replace those specific characters for HTML interceptor, such as &, < or >. Unfortunately, this tag must bind some Javascript stuff, I put these script into common.js. Furthermore, it must embed between STRUTS <html:form> tag, which means it does not work in pure HTML textarea way.

Simple instruction:

  • Include
    in your JSP page
  • Include
    <%@ taglib uri="tags-lams" prefix="lams" %>
  • Change STRUTS HTML tag
    <html:textarea ?>
    <lams:STRUTS-textarea ?>
  • To display content, don?t forget add ?escapeXml=false". It is same handling with FCKEditor field.


This tag provides same function with STRUTS-textarea tag but it is used inside normal HTML form. You can use any attributes which will be rendered exactly same. So, you can treat it as normal HMTL textarea tag. But two things need be careful:

  • name attribute is mandatory.
  • It also need common.js.

DefineLater Tag

All tools need to have a define later screen, which is displayed to the learner when the "define later" flag was turned on in authoring.
To make our pages more consistent, there is a tag that will display the message and a "Try Again" button.

The tag just lays out the fields - you need to define the message and the button name in your language file.

Use of this tag is not compulsory - if your screen needs additional information that won't work well with the tag then don't us the tag. However if your page is the normal looking define later page, please use the tag for consistency.

The tag takes two parameters defineLaterMessageKey, which is the key to the message in your language file, and buttonTryAgainKey, which is the key to the name of the button in your language file. They default to "define.later.message" and "button.try.again" respectively so if you use these keys in your language file then you don't need to include any parameters.

Using Default Keys
(in language file) define.later.message=Please wait for the teacher to complete the contents of this activity. button.try.again=Try again  (in jsp) <div id="page-learner">     <h1 class="no-tabs-below">         ${activity.title}     </h1>     <div id="header-no-tabs-learner">     </div>     <\!--closes header-->      <div id="content-learner">         <lams:DefineLater/>     </div>      <div id="footer-learner">     </div>     <\!--closes footer-->  </div>
Using Different Keys
(in language file) define.later.error=Please wait for the teacher to complete the contents of this activity. try.again.button=Try again  (in jsp) <div id="page-learner">     <h1 class="no-tabs-below">         ${activity.title}     </h1>     <div id="header-no-tabs-learner">     </div>     <\!--closes header-->      <div id="content-learner">         <lams:DefineLater defineLaterMessageKey="define.later.error" buttonTryAgainKey="try.again.button" />     </div>      <div id="footer-learner">     </div>     <\!--closes footer-->  </div>

Help Tag

The Help tag allows you to add a link to a relevant and/or contextualised external help page. The purpose of this help page is to provide assistance the user through details help documentation (e.g. for using a tool).

The Help Tag can be used two method:

1. Contextualised Tool Help

  The link is constructed from two parameters the tool signature (string) and module name (string) i.e. authoring. The tag will display a uniform, help button icon that is aligned to the right.

It is recommended that you use this tag only if you have a default help URL set for your tool. If your default help URL is not set or has a null value then the tag will display nothing. Also note, that it is important that the tool signature value is correct and matches your tool's signature. If the tool signature is incorrect an error will be produced and a cross icon (see below) will be displayed on the page:

For further details on the tool's help URL see Tool ContractTypical example:

<lams:help toolSignature="lanb11" module="authoring"/>

It is possible to used a static variable from an imported class. Example:

<lams:help toolSignature="${NoticeboardConstants.TOOL_SIGNATURE}" module="authoring"/>

The help URL is constructed in the following format:


Typical Output (from above example):

<img src="http://localhost:8080/lams/images/help.png"  onclick="'', 'help')"/>

2. Page-specific Help 

The link is constructed from a single parameter, the page address (string) i.e. My+Page. The tag will display a uniform, help button icon that is aligned to the right.

For further details on the system help URL see LAMS Configuration Settings

Typical example:

<lams:help page="My+Page"/>

The help URL is constructed in the following format:


Typical Output (from above example):

<img src="http://localhost:8080/lams/images/help.png"  onclick="'', 'help')"/>

The icon used is from the common image directory. The icon looks like this:

3. Style Attribute

The default CSS for the help icon makes its placement awkward if not used in the tab environment of author and monitor. If you want to use this tag elsewhere, try the style attribute:

<lams:help style="no-tabs" page="My+Page"/>


Role names for admins and managers are stored in the database as 'COURSE ADMIN' and 'COURSE MANAGER'. To display the internationalised version of a role name, do (for example):

<fmt:message>role.<lams:role role="${}" /></fmt>

This example has the message key in the format 'role.GROUP.ADMIN' (for example). The tag simply translates 'COURSE' to 'GROUP' and replaces the whitespace.

Image Button Wrapper Tag

The Image Button Wrapper tag is used to consistently display two (or more) adjacent image buttons (buttons with css background-image applied) in both left-to-right (e.g. english) and as well in right-to-left (e.g. arabic) directional rendering of the webpage.

Typical use:

<lams:ImgButtonWrapper>     <a href=""  onclick="submitMyItem()" class="button-add-item"> 	<fmt:message key="label.add" />     </a>     <a href="javascript:;"  onclick="cancelMyItem()" class="button space-left"> 	<fmt:message key="label.cancel" />     </a> </lams:ImgButtonWrapper>

The above code produces the following output:

<div id="button-table" class="space-bottom-top">     <div id="button-row"> 	<a href=""  onclick="submitMyItem()" class="button-add-item"> Add </a> 	<a href="javascript:;"  onclick="cancelMyItem()" class="button space-left"> Cancel </a>     </div> </div>


The configuration tag is used to get a value from the Configuration table. For example, to get the current version, use <lams:Configuration key="Version"/>.

This is an alternative to using

<% String version = Configuration.get(ConfigurationKeys.VERSION);%> .... <c:set var="authorurl_params">?loadFile=lams_authoring.swf&....&version=<%=version%>&....</c:set>

The advantage to using the tag is that you avoid scripting, and if a value is needed inside a scriptless tag then scripting is out. The disadvantags is that you have to use the hardcoded version of the configuration parameter (e.g. version) rather than the constant defined in the ConfigurationKeys class.


The out tag is used to replace new line characters \n in a string with the <br> html element.

  • value: Manadatory.  The text to output
  • escapeHtml: Optional.  Escapes the String characters in a String using HTML entities.

Comments and CommentsAuthoring

Using the Comments widget in a tool requires using two tags - CommentsAuthoring in the Advanced tab in Authoring, and Comments in Learning and Monitoring. Examples of their use are taken from the Noticeboard tool. Both tags are designed with default values but you can customise them to suit your tool. The comments values are store in lams_comment* tables.

The comments widget assumes you will add two new fields to the tool content record - allowComments and commentsLikeAndDislike (note these names can be overridden). AllowComments should be a boolean controlling whether or not the comment widget to be used. CommentsLikeAndDislike should be a boolean controlling whether or not the bother like and dislike thumbs appear or just the like. This way the teacher can control whether to use the comments widget, and which thumbs to use, from activity to activity. These two new fields need to be persisted by the tool.

ALTER TABLE tl_lanb11_content ADD COLUMN allow_comments TINYINT(1) DEFAULT 0;
ALTER TABLE tl_lanb11_content ADD COLUMN comments_like_dislike TINYINT(1) DEFAULT 0;

In authoring, these two fields are set. In learning, these two fields are using to control the Comments display.

Comments Authoring

  • allowCommentsVariableName (Optional). Field name to use for the booean flag controlling whether or not display the comments widget. Defaults to allowComments.
  • allowCommentsVariableName (Optional). Field name to use for the booean flag controlling whether or not display the comments widget. Defaults to allowComments.
  • allowCommentLabelKey (Optional). Message key (in the tool's message file) for the allow comments field. Defaults to "advanced.allow.comments".
  • likeOnlyCommentLabelKey (Optional). Message key (in the tool's message file) for the Like Only option. Defaults to "".
  • likeDislikeLabelKey (Optional). Message key (in the tool's message file) for the Like and Disklike field. Defaults to "".

The authoring tag assumes that the following includes are on the jsp page.

<script type="text/javascript" src="${lams}includes/javascript/jquery.js"></script>
<script type="text/javascript" src="${lams}includes/javascript/jquery-ui.js"></script>


  • toolSessionId (Mandatory). Used to identify the tool session to the Comment manager.
  • toolSignature (Mandatory). Used to identify the tool to the Comment manager.
  • height (Optional). Height of the Comments widget. Defaults to auto. Can set it to a fixed size if needed.
  • mode (Optional). Learner vs Monitoring. Defaults to blank, which will be the same as "learner". Set to "teacher" for monitoring.
  • likeAndDislike (Optional). Do you want the Like and Dislike thumbs or just Dike. Defaults to Like only.
  • readOnly (Optional). Show the existing comments but do not allow any changes. Set to true when showing the top ten on a Reflection page. Defaults to false.
  • pageSize (Optional). The number of threads to be loaded at a time (ie the paging setting). Defaults to the system default of 20.
  • sortBy (Optional). Sort by either latest first (value 0) or most likes first (value 1). Defaults to 0.

Normal usage on a learner page - use the default paging option, start with sorting by latest first. AllowComments and LikeAndDislike were set in authoring.

<c:if test="${allowComments}">
<lams:Comments toolSessionId="${NbLearnerForm.toolSessionID}" toolSignature="<%=NoticeboardConstants.TOOL_SIGNATURE%>" likeAndDislike="${likeAndDislike}" />

Top ten entries, view only. Useful on a Reflection page. Shows ten entries initially (overriding the system default) sorting by likes and disables the thumbs, edit and reply buttons.

<c:if test="${allowComments}">
<lams:Comments toolSessionId="${NbLearnerForm.toolSessionID}" toolSignature="<%=NoticeboardConstants.TOOL_SIGNATURE%>" likeAndDislike="${likeAndDislike}" readOnly="true" pageSize="10" sortBy="1"/>

Monitoring view, which allows for Hiding / Editing entries

<lams:Comments toolSessionId="${requestScope.toolSessionID}" toolSignature="<%=NoticeboardConstants.TOOL_SIGNATURE%>" mode="teacher"/>

File Upload

File Upload gives you the small file button and filename next to it upload widget. It ties in with the upload.js file for validation, so it contains the error field (initially hidden) that any error messages are placed in. To make it support all instances of file upload in LAMS, it is very very configurable, but generally you will only need to define two or three parameters. If you are retrofitting it to existing code, check it parameter to see if the default value is fine. If you are using it in new code, try to use the default values.

  • maxFileSize: (Mandatory) The maximum size of the file, already converted to 10MB style format. It is used by the "uploadInfoMessageKey" label.
  • fileFieldname and fileFieldId: the id and name of real "File" input field. This is the name of the field on your form but is hidden on the screen. Normally this is the same and you can just set "fileFieldname" but if you need different values (for example Data Collection tool) then you can set "fileFieldId" to make the "id" field different to the name. Default value is "fileSelector", another coming value is "file".
  • fileInputNameFieldname: field that displays the selected filename. Default value is "fileInputName".
  • fileInputMessageKey: Key to the I18N entry that appears on the upload button (e.g. File or Upload). Default value is "label.authoring.basic.resource.file.input"
  • uploadInfoMessageKey: Key to the I18N entry for "File cannot be executable and maximum file size is 10MB" message. Default value is "". Set this to '-' if you do not want the message - this can be handy if you have a string of file upload fields and you only want to display the message once at the top of the screen (e.g. Image Gallery's multiple upload page).
  • tabindex: tabindex value. No default - of no value given then no tabindex entry will be created on the File button.
  • errorMsgDiv: Only set this if you have more than one file field on the screen (e.g. Data Collection, Image Gallery). It allows you to index your field names so that the errors match up with the file entries. Default value "file-error-msg".
  • fileButtonBrowse: Only set this if you have more than one file field on the screen (e.g. Data Collection, Image Gallery). Use the same index you are using for errorMsgDiv. Default is "fileButtonBrowse"

Example of use from the QTI upload dialog box:

<%@ page import="org.lamsfoundation.lams.util.Configuration" %>
<%@ page import="org.lamsfoundation.lams.util.ConfigurationKeys" %>
<%@ page import="org.lamsfoundation.lams.util.FileValidatorUtil" %>
<c:set var="UPLOAD_FILE_MAX_SIZE"><%=Configuration.get(ConfigurationKeys.UPLOAD_FILE_LARGE_MAX_SIZE)%></c:set>
<c:set var="UPLOAD_FILE_MAX_SIZE_AS_USER_STRING"><%=FileValidatorUtil.formatSize(Configuration.getAsInt(ConfigurationKeys.UPLOAD_FILE_LARGE_MAX_SIZE))%></c:set>
<c:set var="EXE_FILE_TYPES"><%=Configuration.get(ConfigurationKeys.EXE_EXTENSIONS)%></c:set>


<script type="text/javascript">
function verifyAndSubmit() {
	var fileSelect = document.getElementById('file');
	var files = fileSelect.files;
		if (files.length == 0) {
		showFileError('<fmt:message key=""/>');
		return false;
	} else {
		var file = files[0];
		if ( ! validateShowErrorNotExecutable(file, '<fmt:message key="error.attachment.executable"/>', false, '${EXE_FILE_TYPES}')
			 || ! validateShowErrorFileSize(file, '${UPLOAD_FILE_MAX_SIZE}', '<fmt:message key="errors.maxfilesize"/>') ) {
			return false;
	document.getElementById('itemAttachment_Busy').style.display = '';
	return true;


<lams:FileUpload fileFieldname="file" fileInputMessageKey="label.file" maxFileSize="${UPLOAD_FILE_MAX_SIZE_AS_USER_STRING}"/>
<lams:WaitingSpinner id="itemAttachment_Busy"/>

The first few lines set up the file sizes and type strings needed for messages and validation.

The javascript shows how you can use upload.js to validate the file. ValidateShowErrorNotExecutable() displays an error if the file is an executable. ValidateShowErrorFileSize displays an error if the file is too large. ValidateShowErrorImageType() displays an error if the file is not an image file. ClearFileError() and showFileError() clear / display error messages in the error div, which allows tools to implement their own error checks and have the message appear in the same place as the not executable / not image / too big message. Similar methods exist in upload.js to do just the check and not display a message and these may be used with the jquery validator (see the Share Resources tool, addfile.jsp).

Once validated, use the WaitingSpinner tag to display a spinning cursor while the file uploads.

Waiting Spinner

Waiting Spinner is often used along side File Upload but can be used anywhere you need the spinning cursor. A very simple tag but it gives consistency to the cursor across LAMS pages. You will still need to do your own javascript to show/hide the spinner div.

  • id: id to be used for the spinner div. Usually something like "itemAttachment_Busy". Can be omitted if you just want a spinner and do not need to be able to turn it on and off (which is a very unusual case).
  • showInline: If true, shows the cursor inline on the page (so just inserts a <i class></i>). If false, it displays the cursor below the current position and centred on the screen. Default is false.


Portrait is used to display the user's profile picture.

  • userId: (Mandatory)
  • size: (Optional) Controls the size of the image. Valid Values: small, medium, large, xlarge. Defaults to small.
  • round: (Optional) Show portrait in a circle. Valid values: true or false. Defaults to true.

It will insert a URL call to display a portrait, and if the user has not set a portrait then they will get a generic person icon. The colour of the generic icon is based on their userId so they will always get the same colour. The URL call is cached within the page so you cannot display the same user's portrait with two different sizes on the same page. This is done purely for efficiency.

If you need to access the portraits using Javascript then include portrait.js and use the addPortrait( selector, portraitId, userId, size, round, LAMS_URL ) method. The defaults are the same as the tag. Selector is the usual jquery selector used to select the div/cell etc to display the portrait. Your code will look something like:

if (message.teacherPortraitUuid) {
         addPortrait( $('#actionCell #teacher .profilePicture'), message.teacherPortraitUuid, message.teacherUuid, "large", true, LAMS_URL );

Leader Display

Show the portrait and name of the group's leader in an alert like box.

  • username: (Mandatory) Long form of the name e.g. Joe Blow.
  • userId: (Mandatory) Used to display the portrait.

Developing A New Tag

If the new tag may be used in more than one module, it should go in the main tag library in lams_central.

If it is a complex tag, then write a taglib class in the package org.lamsfoundation.lams.web.tag package, in lams_central. Use XDoclet to define your tag details, and then the lams.tld file will be generated when webdoclet is run.

If it is a simpler tag then use a .tag file. Tag files (.tag) should be placed in the /WEB-INF/tags/ folder of the relevant project module.

If the tag is for a particular tool, then it can be left in the tool's project. However it should be done in the same way - a .tag if it is simple or a taglib class using XDoclet if complex.

  • No labels