- The Book of Dojo
- The Dojo Book, 0.4
- Part 1: "Introduction"
- Part 2: "Out of the Box" Dojo
- Part 3: "The Dojo Programming Model"
- Part 4: "More on Widgets"
- Part 5: "Connecting the pieces"
- Part 6: "Customizing Dojo Builds for Better Performance"
- Part 7: "Utilities"
- Part 8: "Internationalization and Accessiblity"
- Part 9: "Dojo Community"
- Part 10: "Fresh From The Shed" Dojo
- BookWriting
- Glossary
Widget Namespaces
Submitted by Carla on Tue, 12/12/2006 - 01:18.
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/../Given
acme widgets are expected to be in acme folder next to dojo folder.<img dojoType="acme:Image" />
acme.widget module is expected to contain the Image widget.
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./dojo /acme/ /acme/widget/Image.js <- defines acme.widget.Image
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:To customize the folder location of module acme call dojo.registerModulePath.<root>/acme/manifest.js
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 ../
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, useregisterNamespace.
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:We want to create custom modules, and decide to put them in:/dojo/dojo.js
/dojo/[whatever else is in the particular dojo install]
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
/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:
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:
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>
