Application Structure

Applications are Dojo modules

Lucid applications are essentially dojo modules. They live in the lucid.apps namespace. The name of the module in this namespace is known as the application’s system name, or sysname. All applications extend the desktop.apps._App class, which contains some bootstrap code and self-management functions.

Metadata

Each app has metadata associated with it, which is stored in the database. This tells Lucid what category it is, which file types it can open, and other things.

Application Skeleton

dojo.provide("lucid.apps.TestApp");

dojo.declare("lucid.apps.TestApp", lucid.apps._App, {
    init: function(args){
        /*Startup code goes here*/
    },
    kill: function(){
        /*Cleanup code goes here*/
    }
});

Here, dojo.provide tells Dojo's package manager that the module loaded OK, and that it does in fact have our TestApp class in it. The dojo.declare call is what makes the class for our application. As you can see, it's extending _App, which takes care of process management, and other low-level tasks in our app.

An application, at the very least, has an init and a kill function. These are run by Lucid when the app starts and when it exits, respectively. You can call the kill function from any function in your code to kill the application. init, on the other hand, is only run once, and by Lucid. Your application shouldn't call the init function.

File layout

The layout for applications consists of the following:

SysName/

SysName.js

SysName being the sysname of your application. Depending on how complex your application is, you can take two routes when choosing a layout.

Single-file applications

These are good for quick applications that don't do too much. If you're writing an application that doesn't need custom widgets <dev-howto-custom-widgets> or templates, and doesn't need too much organization, you can write the entire app in one single class.

Multiple-file applications

Applications that need more structure can use multiple files. This makes the application much easier to maintain. Since Lucid applicatons are basically Dojo modules, we can split it up into several different files, each can have a widget, class, or other resource that the application can use.

With this pattern, usually you put all the dojo.require statements in your app's main file. For example:

dojo.declare("lucid.apps.MyApp");
dojo.require("lucid.apps.MyApp._base");
dojo.require("lucid.apps.MyApp.SomeClass");
dojo.require("lucid.apps.MyApp.SomeWidget");
dojo.require("lucid.apps.MyApp.submethods");

Each module coresponds to a javascript file in the MyApp folder. Fore example, MyApp._base would corespond to MyApp/_base.js. It's important that you load``_base`` before the other modules in your app, otherwise _base will overwrite the declarations.

_base contains the application declaration itself:

dojo.provide("lucid.apps.MyApp._base");

dojo.declare("lucid.apps.MyApp", lucid.apps._App, {
    // ...
});

SomeClass and SomeWidget will contain some resource that we can use in our application. For example:

dojo.provide("lucid.apps.MyApp.SomeClass");

dojo.declare("lucid.apps.MyApp.SomeClass", [], {
    // ...
});

We can also add methods to our original application declaration using dojo.extend:

dojo.provide("lucid.apps.MyApp.submethods");

dojo.extend(lucid.apps.MyApp, {
    // ...
});

This way, we can separate our functions based on what they do. For example, we can have one file that just deals with UI, while another deals with some sort of calculations, etc.

Accessing files/backends bundled with an application

You can get the path to scripts, images, audio, etc. using dojo.moduleUrl:

var soundPath = dojo.moduleUrl("lucid.apps.SystemName", "resources/sound.mp3");

Note that some APIs (such as the Sound API) require that you pass a string. Since moduleUrl returns an object containing a toString method, you need to pass the uri property of the object returned.

soundPath = soundPath.uri;

When used in conjunction with the lucid.xhr method, you can make calls to custom backends packaged with your app this way.

lucid.xhr({
    url: dojo.moduleUrl("lucid.apps.SystemName", "backends/someFile.php"),
    load: function(data){
        console.log("Returned from backend: "+data);
    }
})