Nunaliit2 SDK - Command Line Tool

Table of Content

  1. Obtaining Nunaliit2 SDK
  2. Building Nunaliit2 SDK
  3. Installing Nunaliit2 SDK
  4. Using Nunaliit2 SDK
  5. Running the Atlas as a Daemon
  6. Atlas Directory Structure
  7. Nunaliit SDK Commands
  8. Upload Process
  9. On-Disk Document Format
  10. Upgrading Nunaliit
  11. Atlas Content

Obtaining Nunaliit2 SDK

The Nunaliit2 SDK is a tarball. At this point, there is no single distribution point and must be obtained from a developer or built manually.

Building Nunaliit2 SDK

The Nunaliit2 SDK can be built from the Nunaliit2 source repository. The tools required to build the Nunaliit2 SDK are:

Here are the steps required to build the Nunaliit2 SDK from source.

1. Check out the Nunaliit2 project

> svn co https://svn.gcrc.carleton.ca/nunaliit2/trunk nunaliit2

2. Build Nunaliit2

> cd nunaliit2
> mvn install

3. Locate SDK

There are two versions of the SDK that are packaged during the build process: one TAR file (gzipped) and one ZIP file. For Linux/MacOS installation, the TAR file is preferred.

Both files are located in the directory: .../nunaliit2/nunaliit2-couch-sdk/target

Installing Nunaliit2 SDK

On a Linux installation, one must obtain the TAR file containing the Nunaliit2 SDK. Simply uncompress the installation file in a directory accessible to all that are to use the SDK.

> cd /usr/local
> tar -zxvf nunaliit2-couch-sdk-X.Y-nunaliit.tar.gz
> chmod -R o+r,o+x nunaliit2-couch-sdk-X.Y-nunaliit
> export PATH=$PATH:/usr/local/nunaliit2-couch-sdk-X.Y-nunaliit/bin

Prerequisites

The nunaliit atlas framework depends on the following other projects:

Ubuntu 12.04 is recommended to run the Nunaliit atlas framework, since this is the platform where it is tested the most. Other platforms can be used to run the framework as long as the prerequisites are met.

Besides installed prerequisites, Ubuntu 12.04 requires some configuration fixes so that the framework will function properly:

Installing Java JDK on Ubuntu 12.04

> sudo apt-get install openjdk-6-jdk

Installing CouchDb

TBD

Installing ImageMagick on Ubuntu 12.04

> sudo apt-get install imagemagick

Installing FFMpeg on Ubuntu 12.04

> sudo apt-get update
> sudo apt-get install ffmpeg

Installing libavcodec-extra-53 on Ubuntu 12.04

> sudo wget http://www.medibuntu.org/sources.list.d/precise.list
> sudo wget http://www.medibuntu.org/sources.list.d/precise.list --output-document=/etc/apt/sources.list.d/medibuntu.list
> sudo apt-get update
> sudo apt-get install medibuntu-keyring
> sudo apt-get update
> sudo apt-get install libavcodec-extra-53

Fixing Magic File on Ubuntu 12.04

Edit the file /etc/magic and add the following lines to it:

4       string          ftyp            ISO Media
>8      string          MSNV            \b, MPEG v4 system, version 2
!:mime  video/mp4

Using Nunaliit2 SDK

The Nunaliit2 SDK is a command-line tool that allows a user to create, maintain and publish an on-line atlas. It manages each atlas in its own directory, keeping files relating to an atlas in a confined area of disk, facilitating back-ups and other life cycle tasks.

The Nunaliit2 SDK contains Jetty within its code, permitting the publication of the atlas without requiring any other downloads or set-up. The command-line tool can publish the atlas directly.

The remaining of this section assumes that the Nunaliit2 SDK is installed and that the PATH variable has been updated to include the "bin" directory found within the SDK.

Creating an Atlas

In an atlas creation, a new directory is created already populated with a number of starting files. The command is:

> nunaliit create

The user must answer a number of questions relating to the atlas:

Enter location where atlas should be created: atlas1
Created atlas directory at: /home/jpfiset/eclipse/couchdb/nunaliit2/nunaliit2-couch-command/target/atlas1
Copying templates from: /home/jpfiset/eclipse/couchdb/nunaliit2/nunaliit2-couch-sdk/src/main/templates
Enter the name of the atlas [atlas1]: 
Enter the URL to CouchDB [http://127.0.0.1:5984/]: 
Enter the name of the database where atlas resides [atlas1]: 
Enter the name of the admin user for CouchDB [admin]: 
Enter the password for the admin user [admin_password]: password
Enter the port where the atlas is served [8080]:

If the initial configuration must be changed, it can be accomplished by running the configuration command:

> cd atlas1
> nunaliit config

In general, all commands other than the creation command should be run from the top directory of an atlas as such:

> cd <atlas-dir>
> nunaliit <command>

However, if the command is not run from the top directory of an atlas, the atlas can be specified using the "--atlas-dir" option, as shown here:

> nunaliit --atlas-dir <atlas-dir> <command>

Updating the User Database

In CouchDb, a special database is used to track users called "_users". This database must be modified to work well with Nunaliit. Therefore, a command must be run once each time CouchDb is installed:

> cd <atlas-dir>
> nunaliit <update-user>

Updating and Running an Atlas

Before running an atlas, the files found in the atlas directory must be propagated to their appropriate place. This process is known as "updating" the atlas. This is accomplished using the "update" command.

> nunaliit update

Once an atlas is up to date, it can be published using the "run" command.

> nunaliit run

When the atlas is running, it can be viewed using a web browser. The address for the atlas is the local host, localhost or 127.0.0.1. However, the port on which the atlas is published is configured during the "config" command.

Running the Atlas as a Daemon

A script located in the "extra" and called nunaliit.sh can be used to run the atlas as a daemon. The syntax for this script is:

nunaliit.sh {start|stop|restart|check}

The start command is used to initiate the nunaliit atlas daemon. The stop command is used to terminate the currently running daemon. The restart command combines both stopping and starting the daemon.

The check command is used verify the configuration and whether the daemon is running, or not.

Automatically starting Atlas Daemon

On an Ubuntu platforms, it is possible to make the atlas daemon start automatically when the server boots. This approach is based on the "nunaliit.sh" script found in the "extra" directory.

> cd /etc/init.d
> sudo ln -s <atlas-dir>/extra/nunaliit.sh nunaliit
> sudo update-rc.d [-n] nunaliit defaults 95

Configuring Daemon

The "nunaliit.sh" script is written over every time that the nunaliit config command is run. Therefore, the script should not be manually modified. Instead, a file can be created which, if it exists, is included by "nunaliit.sh". This file to be included must reside in the "extra" directory and named "config.sh".

The most common use of the external configuration file is to set the user that the daemon is run as. This is accomplished by creating a file (<atlas-dir>/extra/config.sh) with the following content:

NUNALIIT_USER=<user>

Atlas Directory Structure

An atlas directory is created using the "create" command. At first, an atlas is populated with a number of default files. Most of these files can be modified to change the look and behaviour of the atlas.

This section discusses the directory structure of the atlas and the types of files found in it.

The top directory contain a number of sub-directories:

Nunaliit SDK Commands

help

nunaliit help [<command>]

This command provides general help about syntax and purpose, if a command is not specified. If a nunaliit command is specified as argument, help is reported about the syntax and purpose of the requested command.

create

nunaliit [<global-options>] create [<create-options>]

This command creates a new directory structure to hold the content of an atlas managed by the nunaliit framework. Then, the configuration command is run to set-up the apppropriate configuration properties.

The options that can be specified for the create command (<create-options>) are defined as follows:

config

nunaliit [<global-options>] config

This command configures the atlas by asking the user a number of questions and setting the atlas configuration properties accordingly.

update-user

nunaliit [<global-options>] update-user

This command updates the database used to managed users on CouchDb. This updates is required for the proper functioning of the atlas framework.

This command needs to be run only once for each CouchDb installation.

update

nunaliit [<global-options>] update

This command updates the CouchDb database used to support the atlas with the files found in the atlas directory. This command should be run every time changes are performed on the files found within the atlas directory.

If the CouchDb database associated with the atlas is not yet created, the update command creates it.

The update process is complex and encompasses many activities:

run

nunaliit [<global-options>] run

This command updates starts an HTTP service which serves the content of the atlas. The address used by the service is the localhost. The port used by the service is specified during configuration.

During the run command, the console output is used to report log messages. The service is ended by using CTRL-C

Log messages are also sent to a file located in the "logs" directory

dump

nunaliit [<global-options>] dump [<dump-options>]

This command takes a snapshot of some or all the documents found in the database associated with the atlas and store it to disk. This snapshot can be later restored using the "restore" command.

The options that can be specified for the dump command (<dump-options>) are defined as follows:

restore

nunaliit [<global-options>] restore --dump-dir <dir> [<restore-options>]

This command restores documents previously saved using the "dump" command. It can restore a complete snapshot, when the

The options that can be specified for the restore command (<restore-options>) are defined as follows:

<global-options>

Global options are accepted by a number of commands and are defined as follows:

Upload Process

The Nunaliit framework uses an upload process during atlas updating, upgrading and restoring. This process modifies documents in the database with the content of documents found on disk.

When the upload process installs a document in the database, it creates a fingerprint of the document that it stores along with the document. When this document is modified, the fingerprint computed by the upload process no longer matches the content of the document. By verifying the fingerprint stored with a document, the upload process can determine if the document was modified since it was last installed in the database.

The upload process uses the following appraoch for each document to be uploaded:

  1. The document to be uploaded is read in memory, a fingerprint is computed against it and the fingerprint is added to the document.
  2. The database is queried for a document that has the same identifier.
  3. If a document with the same identifier is not found in the database, the document in memory is uploaded and the process ends.
  4. If the document found in the database is equivalent to the one in memory, the process ends.
  5. If the document found in the database does not contain a fingerprint, it is deemed modified. In this case, the upload process is aborted and an error is reported.
  6. If the document found in the database contains a fingerprint and that the fingerprint does not match its content, the document is deemed modified. In this case, the upload process is aborted and an error is reported.
  7. The document in memory is uploaded to the database.

On-Disk Document Format

Documents in CouchDb are represented as JSON objects. Therefore, all document transfers between CouchDb and applications are performed using JSON objects. In the Nunaliit framework, there are a number of instances where documents are stored on disk within the atlas directory. This section describes the format used by Nunaliit to load documents from disk.

A document stored on disk is represented by a directory. The name of the directory is not relevant to the loading process and should be selected to help user locate documents. This directory is known as the "document directory".

In the document directory, each entry (file or sub-directory) represents a key of the top-most object that constitutes the document. Each file contains the value associated with the key. Each sub-directory contains the object or array value associated with the key.

For each entry (file and sub-directory) in the document directory, a key is derived from the name. The extension for the entry name is used to determine the format of the entry while the remainder of the name is used as the key.

For a file entry with an extension of "txt", the content of the file is used as a string value. For a file entry with an extension of "json", the content of the file is interpreted as JSON and used as the value.

For a directory entry without an extension, the content of the directory is used to create an object that is used as the value. The process to load this object is identical to the one used by the document loader, and thus is recursive.

For a directory entry with an extension of "array", the content of the directory represents an array. The names of the entries in directory are sorted and values are loaded in this order.

Here is an example illustrates this process. In this example, the directory structure is:

/
|- _id.txt : 123456
|- a.txt   : Just a test
|- b.json  : {"array":[1,2,3]}
|- inner
|  |- c.txt  : Another string value
|  |- d.json : {}
|- e.array
   |- 0.txt : one
   |- 1.json : 2  

From the above directory structure, the loading process would create a JSON object equivalent to:

{
	"_id":"123456"
	,"a":"Just a test"
	,"b": {
		"array":[1,2,3]
	}
	,"inner":{
		"c":"Another string value"
		,"d": {}
	}
	,"e":["one",2]
}

Attachments

CouchDb associates files to documents as attachments. Attachments are saved in a document under a special key: "_attachments"". On disk, the attachments are saved in a directory called "_attachments" in the top document directory.

Each file found in the "_attachments" directory structure is uploaded as an attachment to the document, with a name that is the relative path from the "_attachments" directory. Sub-drectories to the "_attachments" directory have no meaning other than to contribute to the naming of the files deemed as attachments.

Other information is associated with attachments, such as the content-type. This information is stored in a file adjacent to the attachment itself. This information file has the same name as the attachment, however it is appended with "._nunaliit". The content of the information file is plain text that contains a JSON object that is examplified as:

{
	"name": <attachment-name>
	,"content_type": <content-type>
}

The <attachment-name> is a string specifying the name of the attachment and is useful in case the name associated with an attachment can not be converted into a directory structure. The field <content-type> is a string depicting the content type of the attachment, such as "text/plain", "text/html" or "video/mp4".

Upgrading Nunaliit

Over the life of an atlas, new releases of Nunaliit might become available. This section discusses the procedure to migrate from one version of Nunaliit to another. In this process, new and updated libraries will be installed as well as new and updated documents that are specified by the framework.

At a high level, the upgrade process follows these steps:

  1. Install new version of Nunaliit
  2. Stop atlas
  3. Re-configure atlas
  4. Update atlas
  5. Restart atlas

Install new version of Nunaliit

When a new version of Nunaliit is installed on a platform, it should be hosted in a directory different than the previous version. The old version of the Nunaliit framework should be kept until the new atlas is performing properly. This enables a user of the Nunaliit framework to revert to an earlier version.

Installing Nunaliit is as simple as uncompressing the distributed file in its own directory. To make this new version active, modify the PATH variable used by the operating system to detect executable files. The PATH variable should include the "bin" directory of the new installation, not the old one.

Stop the Atlas

Stopping the atlas is dependent on the way the atlas was started. If the atlas was started using the "run" command, then pressing CTRL-C in the console window where the atlas is run should be sufficient. If the atlas was started as a daemon, the following command should be used:

.../nunaliit.sh stop

Re-Configuring the Atlas

Some of the files in the atlas directory reference the location of the Nunaliit framework. These files must be updated to reference the new framework location. This is accomplished by running the configuration command. In the case of re-configuring, all default values can be accepted during the "config" command.

> cd <atlas-dir>
> nunaliit config

Update Atlas

Updating the atlas is required to load new and modified documents and libraries. If an updated document was changed manually in the database, then the document is skipped during the upload process. This means that a user upgrading Nunaliit should remain vigilent of the errors reported during the update process.

Re-Starting Atlas

After the re-configuration, the script used to start Nunaliit as a daemon is modified. One should review this file to ensure that all properties are in order. Then:

> <atlas-dir>/nunaliit.sh start

Reverting to an older version of Nunaliit

Reverting to an older version of Nunaliit is similar. Instead of installing a new version of the Nunaliit framework, change the PATH variable back to the "bin" directory of the desired version. Then, follow the remaining steps of this section.

Atlas Content

There are two main types of documents that are served from a running instance of the atlas framework: Web Resources and Database Documents.

Web resources are files that generally comprised a web site and include such things as HTML files, CSS files, Javascript libraries, images, etc. A number of web resources are provided by the atlas framework, itself. Others are specified by the atlas designer by including them in the "htdocs" directory of the atlas.

On the other hand, database documents are JSON object that are stored in CouchDb. These documents can be access directly by providing the document identifier to the database, or via multiple views that are installed by the atlas framework. As with web resources, a number of database documents are provided by the framework. Atlas designers can specify documents to be loaded to the database by including them in the "docs" directory of the atlas.

Althgough database documents can be specified and uploaded by the framework, the majority of documents found in the database are created and updated by using the atlas itself. Geometries, comments, and most of the interactions that users have with the atlas ends up recorded as a database documents.

The main distinction between web resources and database documents is that web resources are static, while database documents can be modified at run-time. Updating an atlas provides an opportunity to the atlas designer to change the web resources. However, between updates, web resources remain static.

All documents, including those provided by the framework, can be modified by users as long as the modifications respect the authorization rules. Therefore, the behaviour controlled by the content found in database documents can be modified and customized to fit an atlas. On the other hand, if a database document provided by the framework was modified by a user, this document is not upgraded while installing a new revision of Nunaliit.

Design Documents

In CouchDd, there are a special class of documents called "Design Documents". These documents have identifiers that begins with the prefix "_design/" and are used to provide index functions, validation functions, list functions and show functions. These document generally contains web resources for on-line applications served out of the database.

In the Nunaliit framework, a number of design documents are in use:

URLs

The Nunaliit framework serves the web resources and the database documents through an HTTP connect, accessible from a web browser. For simplification, the all URL paths used by the atlas web application are relative to the root, where the atlas web resources are served. URL redirection is used to make CouchDb resources appear adjacent to one another.

Here are the paths served by the Nunaliit framework:

Configuration

HTML documents and other web resources provided by an atlas designer should be located in the "htdocs" sub-directory of the atlas directory. In particular, HTML documents that are expected to perform interactions with the framework should:

The CSS resources required by the Nunaliit framework should be defined in the header of a HTML file as follows:

<link rel="stylesheet" href="js-external/css/jquery-ui/smoothness/jquery-ui.custom.css" type="text/css" />
<link rel="stylesheet" href="js-external/css/jquery.lightbox-0.5.css" type="text/css" />
<link rel="stylesheet" href="nunaliit2/css/basic/nunaliit2.css" type="text/css" />
<link rel="stylesheet" href="_list/css_merge/css" type="text/css" />

The Javascript libraries required by the Nunaliit framework should be defined in the header or the body of a HTML file as follows:

<script type="text/javascript" src="js-external/js/jquery.min.js"></script>
<script type="text/javascript" src="js-external/js/jquery-ui.min.js"></script>
<script src="http://maps.google.com/maps/api/js?v=3.3&sensor=false"></script>
<script type="text/javascript" src="js-external/OpenLayers/OpenLayers.js"></script>
<script type="text/javascript" src="js-external/js/jquery.lightbox-0.5.js"></script>
<script type="text/javascript" src="js-external/js/jquery.cycle.pack.js"></script>
<script type="text/javascript" src="js-external/js/jquery.form.js"></script>
<script type="text/javascript" src="js-external/js/jquery.cookie-1.0.js"></script>
<script type="text/javascript" src="js-external/js/sha1.js"></script>
<script type="text/javascript" src="lib/atlas.js"></script>
<script type="text/javascript" src="nunaliit2/nunaliit2.js"></script>
<script type="text/javascript" src="nunaliit2/nunaliit2-couch.js"></script>
<script type="text/javascript" src="lib/utils.js"></script>
<script type="text/javascript" src="config/configuration.js"></script>
<script type="text/javascript" src="nunaliit_custom.js"></script>

The initialization of the Nunaliit atlas framework is performed in multiple steps:

  1. The initialization should be started by the application once the document is loaded
  2. The atlas framework creates components that configured in a default manner
  3. Custom configuration code is called
  4. Control is returned to the application via a callback

Initialization is started by the application by calling a function called "runConfiguration". This should be done after the document completed to load. Since jQuery is available (jQuery is required by the Nunaliit framework), a simple way to perform this is to use the jQuery's "ready" function, as demontrated in this example:

jQuery().ready(function() {
	runConfiguration({
		configuredFunction: main_init
		,rootPath: './'
	});
});

The runConfiguration() takes an object as argument to pass options to the configuration process. There are two options that can be specified:

During the configuration process, custom configuration code is called. This is covered in its own section, later.

At the end of the framework configuration, a callback is executed. This callback can be thought of as the application's main entry point or main function. As described earlier, this callback is specified in the "runConfiguration()" function. The main function receives an object, which contains all configuration information. The structure of this object is:

From the main application function, an application can create a map, a side text panel, and many more widgets, based on the configuration. This is covered later. The next script fragment shows the "runConfiguration()" and application main function together:

function main(config){
	// Here starts the application
};

jQuery().ready(function() {
	runConfiguration({
		configuredFunction: main
		,rootPath: './'
	});
});

Custom Configuration

All tools provided by the framework explicitely include a Javascript file named "nunaliit_custom.js" and located in the top most directory of the atlas (root). If an atlas designer is interested in modifying the configuration globally, before any tool has an opporunity to begin, it can be accomplished by adding custom code to a file named "nunaliit_custom.js" in the "htdocs" sub-directory of the atlas directory. If this file exists at run-time, it is loaded and all functions exposed by this file are available to the web application.

To intercept configuration of the Nunaliit framework, an atlas designer must specify a special function. This function should be located at in the Javascript name space at window.nunaliit_custom.configuration. The following example shows a script to perform custom Javascript operations:

;(function($n2){

if( typeof(window.nunaliit_custom) === 'undefined' ) window.nunaliit_custom = {};

// This is the a custom function that can be installed and give opportunity
// for an atlas to configure certain components before modules are displayed
// @param config Object that contains all configuration
// @param callback Function to be called when custom code is complete. This
//                 allows asynchronous calls to be performed in the custom
//                 code. 
window.nunaliit_custom.configuration = function(config, callback){

	// --- This is where custom code would be inserted ---

	// Done with configuration, perform the offered callback
	// to complete configuration and initialize application.
	callback();
};

})(nunaliit2);

As shown in the example above, the callback function given in argument must be called at the end of the customization. This approach is used to enable custom code to perform asynchronous calls. If the callback function is not called, then the atlas will not load.

The configuration object provided as argument is described in a previous section and is fully populated by the time the custom configuration function is called.

All web pages created by an atlas designer should include "nunaliit_custom.js" to provide the custom code an opportunity to run.

Custom Display

As part of custom configuration, it is possible to influence how a document appears by adding custom values to the document before it is displayed by the "ShowService". Schemas are used to render the content of a document. However, schemas contain only simple templates and do not provide a way to perform complex computations based on the content of the document.

The "ShowService" offers the opportunity to install a function that may modify any document before it is presented to the templating process. The following script demonstrates this capability:

window.nunaliit_custom.configuration = function(config, callback){

	/*
	 * This is the function where documents are modified before being displayed
	 * by the Show Service
	 */
	config.directory.showService.options.preprocessDocument = function(doc) {
		
		// At this point, perform any modification required
		doc.justATest = 'TestValue';
	
		return doc;
	};
	
	// Done with configuration
	callback();
};

The example above shows the ability of installing a "preprocessDocument" function to the ShowService during custom configuration. Modifications made to a document during the preprocess function are available to the schema templates.

Custom Editing

When a document is being edited, a number of views of the document are presented to allow a user to modify the content of the document. One of those views is based on the schema associated with the document. Since a schema offers only a template, it is not possible to specify complex operations using the template alone. There is a facility, using the SchemaEditor, to modify the HTML produced by the template. To do so, one must register a "post process" function with the document editor based on schema. The following script shows how this can be accomplished:

if( typeof(window.nunaliit_custom) === 'undefined' ) window.nunaliit_custom = {};

// This is the a custom function that can be installed and give opportunity
// for an atlas to configure certain components before modules are displayed
window.nunaliit_custom.configuration = function(config, callback){

	/*
	 * The following function is called after a schema editor has been
	 * called to display a document. This is useful to add UI elements
	 * to the edit window.
	 * @param doc {Object} Document that is being edited
	 * @param $div {Object} jQuery element that contains the rendered template
	 *                      for editing. 
	 */
	config.directory.schemaEditorService.addPostProcessFunction(function(doc, $div) {
	
		// Find elements with class 'insertRevision' and change content with document
		// revision
		$div.find('.insertRevision').text(doc._rev);
	});

	// Done with configuration
	callback();
};

The simplistic example above shows how to enable this feature within the custom configuration function. The custom configuration function, within "nunaliit_custom.js", is the appropriate place to define this function as to make the changes available to all Nunaliit tools.

Custom Document Creation

Within the atlas framework, when a new document is created, it is generally done spcifying a document schema. The schema provides a basic template for a new and empty document. If a more complex process is required when creating a new document, it is possible to install a function with the schema repository to intercept all new documents created from a schema and modify the content of the document. The following script demonstrate how a custom function can be installed:

if( typeof(window.nunaliit_custom) === 'undefined' ) window.nunaliit_custom = {};

// This is the a custom function that can be installed and give opportunity
// for an atlas to configure certain components before modules are displayed
window.nunaliit_custom.configuration = function(config, callback){

	/*
	 * The following function is called when a document is created from
	 * a schema.
	 */
	var repositoryFunctions = config.directory.schemaRepository.getRepositoryFunctions();
	repositoryFunctions.addOnDocumentCreateFunction(function(doc, schema){
	
		if( schema.name === 'mySchema' ){
			doc.mySchema = ['something special'];
		};
	
	});
	

	// Done with configuration
	callback();
};

The function called at creation is given both the new document and the schema used to create it. The schema can be used to discriminate which documents require modifications. The document given in argument can be modified, if it is needed.

The example above shows how the custom creation function can be added via the use of the custom configuration function. This is the appropriate location for this definition so as to have all tools offered in the framework behave the same when a new document is created.

Module Document

One of the way to build an atlas page is to use a module document. A module document specifies the characteristics of a module, such as which map layers are used, what the introductory text is, which schemas are used, etc. A module document can be stored in the database or specified in-line by in Javascript code. With a module document, the ModuleDisplay class can be used to display the module to a web page, by specifying where the elements should be displayed.

Module Document

The example of a module document is shown here to help with explanation:

{
	"nunaliit_module": {
		"title":"Generic Atlas"
		,"introduction": {
			"type": "html"
			,"content": "<div class=\"intro\"><b>Welcome to a Nunaliit2 Atlas served from CouchDb</b><br/><a href=\"./tools/index.html\">Nunaliit Tools</a></div>"
		}
		,"map":{
			"coordinates": {
				"initialBounds": [-75.72,45.41,-75.67,45.43]
			}
			,"backgrounds": [
				{ 
					"name": "Google Satellite"
					,"type": "Google Maps"
					,"options": {
						"type": "SATELLITE"
						, "numZoomLevels": 19 
					}
				}
				,{ 
					"name": "Google Hybrid"
					,"type": "Google Maps"
					,"options": {
						"type": "HYBRID"
						,"numZoomLevels": 19
					}
				}
				,{ 
					"name": "Google Physical"
					,"type": "Google Maps"
					,"options": {
						"type": "TERRAIN"
						,"numZoomLevels": 19 
					}
				}
			]
			,"overlays": [
				{
					"name": "Approved Layer"
					,"type": "couchdb"
					,"options": {
						"layerName": "approved"
					}
					,"featurePopupDelayMs": 0
					,"useHoverSound": true
				}
				,{
					"name": "Public"
					,"type": "couchdb"
					,"options": {
						"layerName": "public"
					}
					,"featurePopupDelayMs": 0
					,"useHoverSound": true
				}
			]
			,"addPointsOnly": false
			,"toggleClick": true
		}
		,"display":{
			"defaultSchemaName":"genericDoc" 
		}
		,"edit":{
			"defaultSchemaName": "genericDoc"
			,"newDocumentSchemaNames": "ALL_SCHEMAS" 
		}
	}
}

At the top level of a module document, a key "nunaliit_module" must be present. This key is associated with an object (module object) that contains all the pertinent information relating to a module. The keys that can be specified in a module object are:

The module object can also define a key named "map", which is associated with an object that describes a map that can be displayed. The map description object is defined with the following keys:

When defining a map background, the object must contain a key named "name" for specifying the name of the background, a key named "type" for specifying the type of the background and a key named "options", which is an object that contains information about the background depending on the type of background. The possible background types are: "Bing", "Google Maps" and "wms".

A "Bing" background layer must specify the following options:

A "Google Maps" background layer must specify the following options:

A "wms" background layer refers to a layer that is served from a WMS server. The object associated with a WMS layer must specify the following options:

When defining map overlays, any layer definition acceptable for background can be included as an overlay. When defining an overlay, the overlay object is specified as follows:

A "couchdb" overlay is associated with an options object defined as follows:

A "wfs" overlay is associated with an options object defined as follows:

Module Display

A document module can be rendered by a web application by using the module display function. There are two methods: using an in-line module document, or using a module document saved in the database.

The following script shows how to call the display function:

function main_init(config) {
	
	// Get module name from URL parameters
	var moduleName = 'generic.module:default';

	var moduleDisplay = new $n2.couchModule.ModuleDisplay({
		moduleName: moduleName
		,config: config
		,titleName: 'title'
		,mapName: 'map'
		,sidePanelName: 'side'
		,searchPanelName: 'searchInput'
		,onSuccess: function(){}
		,onError: function(err){ alert('Unable to display module('+moduleName+'): '+err); }
	});
};

The instance of ModuleDisplay is initialized using a object that provided all necessary parameters. This initialization object is defined as follows:

Schema Document

Schemas are used to define how a database document is displayed to the user within the context of an atlas. There are multiple instances when a user can be presented the content of a database document, and a schema handles all those cases. Among those cases are the "display" case, when a user is focusing on a particular database document. Another case is the "brief" view, which is displayed in a bubble when a user mouses over a map feature that relates to the database document. Yet another case is the "edit" view, displayed when a user is editting a database document.

In Nunaliit, schemas used a technology called "Mustache templates" (http://mustache.github.com/) to render the HTML fragments necessary to display the information contained in a document. The Mustache templating was designed specifically for this purpose and documentation for this technology is readily available on the Internet.

A database document is associated with a schema by recording the schema name in a special key named "nunaliit_schema", at the top level of the database document. The document, offered here as an example, is associated with a schema named "placename":

{
	"_id": "just a test"
	,"place": {
		"name": "test place"
		,"description": "just a description"
	}
	,"nunaliit_schema": "placename"
}

A schema is a document that can be saved in the database. When schemas are saved in the database, it offers greater flexibility since the information recorded and display for each document type can be tailored at run-time to suit the atlas' needs.

Following is an example of a schema document:

{
   "_id": "myschema:placename",
   "nunaliit_type": "schema",
   "nunaliit_schema": "schema",
   "name": "placename",
   "label": "Place Name",
   "isRootSchema": true,
   "create": {
       "place": {
           "name": "",
           "description": ""
       },
       "nunaliit_schema": "placename"
   },
   "brief": "PlaceName({{#place}}{{name}}{{/place}})",
   "display": "<div>\n\t{{#place}}\n\t\t{{#name}}\n\t\t\t<div>\n\t\t\t\t<div class=\"label n2_localize\">Name</div>\n\t\t\t\t<div class=\"value\">{{name}}</div>\n\t\t\t\t<div class=\"end\"></div>\n\t\t\t</div>\n\t\t{{/name}}\n\t\t{{#description}}\n\t\t\t<div>\n\t\t\t\t<div class=\"label n2_localize\">Description</div>\n\t\t\t\t<div class=\"value n2s_preserveSpaces\">{{description}}</div>\n\t\t\t\t<div class=\"end\"></div>\n\t\t\t</div>\n\t\t{{/description}}\n\t\t{{/place}}\n\n\t</div>",
   "form": "<div>\n\t{{#place}}\n\t\t<div>\n\t\t\t<div class=\"label n2_localize\">Name</div>\n\t\t\t<div class=\"value\"><input type=\"text\" class=\"{{#:input}}name{{/:input}}\"/></div>\n\t\t\t<div class=\"end\"></div>\n\t\t</div>\n\t\t<div>\n\t\t\t<div class=\"label n2_localize\">Description</div>\n\t\t\t<div class=\"value\"><textarea class=\"{{#:input}}description{{/:input}}\"></textarea></div>\n\t\t\t<div class=\"end\"></div>\n\t\t</div>\n\t{{/place}}\n</div>",
   "export": [
       {
           "select": "place.name",
           "label": "name"
       },
       {
           "select": "place.description",
           "label": "description"
       }
   ],
   "relatedSchemas": [
       "genericMedia"
   ]
}

An explication of each entry of the schema document is offered here:

Because the "display" field of a schema is a Javascript string containing a Mustache template of a HTML fragment, many characters must be escaped which hinders comprehension. However, if one was to access this field using an editor that showed the content without escaping characters, this is what the "display" field from the example above would look like:

<div>
	{{#place}}
		{{#name}}
			<div>
				<div class="label n2_localize">Name</div>
				<div class="value">{{name}}</div>
				<div class="end"></div>
			</div>
		{{/name}}
		{{#description}}
			<div>
				<div class="label n2_localize">Description</div>
				<div class="value n2s_preserveSpaces">{{description}}</div>
				<div class="end"></div>
			</div>
		{{/description}}
	{{/place}}
</div>

In the same manner, the "form" field from the schema example is unescaped here to help with comprehension:

<div>
	{{#place}}
		<div>
			<div class="label n2_localize">Name</div>
			<div class="value"><input type="text" class="{{#:input}}name{{/:input}}"/></div>
			<div class="end"></div>
		</div>
		<div>
			<div class="label n2_localize">Description</div>
			<div class="value"><textarea class="{{#:input}}description{{/:input}}"></textarea></div>
			<div class="end"></div>
		</div>
	{{/place}}
</div>

Mustache defines how, given a context JSON object (a database document), a HTML fragment is generated based on the values found in the object. However, there are two other key concepts necessary to understand how the templating works within Nunaliit:

  1. Elements classes understood by Nunaliit
  2. Mustache functions provided by Nunaliit

Once a HTML fragment is generated using the Mustache templating, the Nunaliit framework analyzes the result for certain classes and modifies the HTML tags accordingly. Here is a list of the classes understood by the Nunaliit framework:

Besides pre-defined HTML classes, the Nunaliit framework adds functions and special accessors to context Javascript objects before the are processed by the Mustache templating process. All The following functions and accessors are available to a Mustache template when in use with the Nunaliit schemas: