This page has been moved into the book in this chapter. Ignore this page....
TODO: Probably need to separate section on using custom widgets from the section on how to write them. Also, some of this information applies to making custom modules (not necessarily containing widgets)... needs to be organized.
DUPLICATE -this was moved to the book
here. Still need to move the custom module info out.
Overview
Widgets are combined into groups called namespaces.
All the widgets built into Dojo are in the "dojo" namespace, but someone else could write their own widgets and put them in a different namespace. For example, you could write your own button and checkbox widgets, and put them into an "acme" namespace. Then "acme:Button" would be your button, and would be unrelated to the button object built into dojo, called "dojo:Button".
Usage
Defaults have been chosen to reduce boilerplate. A namespace maps to a top-level module by default. A top-level module path defaults to
dojo/../<module>, and widgets are expected to be in
<module>.widget.
Given
<img dojoType="acme:Image" />
acme widgets are expected to be in
acme folder next to
dojo folder
.
acme.widget module is expected to contain the
Image widget.
<root>/dojo
<root>/acme/
<root>/acme/widget/Image.js <- defines acme.widget.Image
Loading
acme.widget.Image module is the only requirement for using
acme:Image in this configuration. You can load that module as part of a build, by calling
dojo.require, or automatically.
To use a folder location other than
../acme call
dojo.registerModulePath.
To select a widget module other than
acme.widget, call
dojo.registerNamespace.
Automatic Loading
To allow automatic loading of widgets in a namespace, include a manifest file. For the example above, the default resource for the manifest would be:
<root>/acme/manifest.js
To customize the folder location of module
acme call
dojo.registerModulePath.
For most users employing the auto-require system, the manifest file contains a call to
dojo.registerNamespaceResolver. A namespace resolver tells Dojo what module to load for a named widget.
dojo.provide("acme.manifest");
dojo.require("dojo.string.extras");
dojo.registerNamespaceResolver("acme",
function(name){
return "acme.widget."+dojo.string.capitalize(name);
}
);The input string
name will always be lower-case. So this resolver triggers loading of module
acme.widget.Calendar for widget
acme:calendar.
The load-time module is not necessarily the same as the widget class module. For example, the
acme.widget.Calendar class might be loaded via
acme.widget.allWidgets.
The resolver tells dojo the module to require to load a widget.
To select a widget class module other than
acme.widget, call
dojo.registerNamespace.
API
dojo.registerModulePath(module, path): maps a module name to a path (formerly
setModulePrefix).
An unregistered module is given the default path of
../<module>, relative to Dojo root. For example, module
acme is mapped to
../acme. If you want to use a different module name, use
registerModulePath.
dojo.registerNamespace(namespace, widget_module [, resolver]): maps a module name to a namespace for widgets, and optionally maps widget names to modules for auto-loading.
An unregistered namespace is mapped to an eponymous module. For example, namespace
acme is mapped to module
acme, and widgets are assumed to belong to
acme.widget. If you want to use a different widget module, use
registerNamespace.dojo.registerNamespaceResolver(namespace, resolver): a resolver function maps widget names to modules, so the widget manager can auto-load needed widget implementations.
The resolver provides information to allow Dojo to load widget modules on demand.
When
a widget is created, a namespace resolver can tell Dojo what module to
require to ensure that the widget implementation code is loaded.
The input string in the
name argument will always be lower-case.
dojo.registerNamespaceResolver("acme",
function(name){
return "acme.widget."+dojo.string.capitalize(name);
}
);
Examples
Let's say we have a Dojo install at root:
/dojo/dojo.js
/dojo/[whatever else is in the particular dojo install]
We want to create custom modules, and decide to put them in:
/acme
Note that the path to
acme from
dojo is:
../acme
For the widget examples, let's say we made some custom widgets, including one called
acme.widgets.Calendar, and put them in:
/acme/widgets/variousWidgets.js
Automatic Loading
Main document
<script src="/dojo/dojo.js"></script>
<script>
dojo.require("dojo.widget.*");
</script>
Include a manifest file: /acme/manifest.js
dojo.provide("acme.manifest");
dojo.registerNamespaceResolver(function(name) {
return "acme.widgets.variousWidgets";
}); To support markup like so:
<div dojoType="acme:calendar"></div>
The acme namespace triggers require of acme.mainfest. The resolver is used to match calendar to a required module (i.e. acme.widgets.variousWidgets). Then acme.widgets module is searched for calendar implementation matching the current rendering environment.
Explicit Loading
Main document
<script src="/dojo/dojo.js"></script>
<script>
dojo.require("acme.widgets.variousWidgets");
</script>
Supports markup like so:
<div dojoType="acme:calendar"></div>
acme.widgets module is searched for calendar implementation matching the current rendering environment.
Non-Widget Resources
Main document
<script src="/dojo/dojo.js"></script>
<script>
dojo.require("acme.lib");
</script>
acme/lib.js file:
// ... additional code ...
Builds
With a build you can use any of these formats, but a manifest is not required.
Main document
<!-- dojo.js is a build -->
<script src="/dojo/dojo.js"></script>
<!-- dojo.require(s) can be here, although they are ignored -->
Supports markup like so:
<div dojoType="acme:calendar"></div>