This article describes, how you can create your own dojo namespace within a reusable django application when using dojango. It should give you an idea, where you place your javascript files and how you could structure your dojo namespace directory. When using dojango, where you are able to switch the source of dojo (a remote CDN or a local version), there are several things to consider when creating your own namespace.

First I’ll explain how dojo uses namespaces and how you can preload files with it and afterwards i’ll describe how you setup a django project using dojango and adding your own django app with its own dojo namespace.

Explaining the Dojo Loader

It is important to understand, how dojo loads files and how dojo utilizes their namespace structure before creating your own one.

At the beginning there is the dojo base system, that is loaded via a script tag in your page and which enables the dojo namespace on your page:

<script type="text/javascript"
    src="/path-to-dojo-dir/dojo/dojo.js"
    djConfig="parseOnLoad: true, isDebug: false">
</script>

As you maybe already know, dojo comes with the two other namespaces dijit (layout and form widgets) and dojox (extensions for dojo and experimental stuff) and an addtional namespace called util, where the test-runner of dojo is located (concerning js namespace and dojo loadable module). You can see that stated in the 4 directories dojo delivers and where each directory represents a namespace:

.
|-- dijit
|   | -- ...
|   | -- Editor.js
|   `--....
|-- dojo
|   | -- ...
|   | -- dojo.js
|   `-- ...
|-- dojox
`-- uti

Beyond loading the dojo base system you are then able for example to load the richtext editor widget by using the dojo.require function, that belongs to the dojo base system. By calling this function dojo resolves the namespace dijit relative to the parent directory (../) where the file dojo/dojo.js resides. The following dojo.require call would load the file dijit/Editor.js and all dependant classes and functions used by the richtext editor. If the dijit.Editor already was loaded it wouldn’t refetch the JavaScript files:

<script type="text/javascript">
    dojo.require("dijit.Editor");
</script>

You can change the namespace resolving behavior by using the dojo.registerModulePath function. If you do that in front of the dojo.require call, the dojo module loader will deliver requested files of that defined namespace from the given path:

dojo.registerModulePath("dijit", "/another-path-to-dijit");
// or relative to the dojo/dojo.js file
// dojo.registerModulePath("dijit, "../relative-path-to-dijit");

Besides that we also need to differentiate between a local and a xd (crossomdain) remote version to understand the module loading of dojo.

For a local loaded version (see Add Dojo Source Guide) you just need to place your new dojo namespace directory (suggesting “myapp”) next to the dojo, dijit and dojox folder and you then can load your dojo javascript module myapp/MyModules.js with dojo.require(“myapp.MyModule”). Alternatively you can place your dojo module “myapp” somewhere else and register that path with dojo.registerModulePath.

Assuming you load dojo from an external CDN like AOL or Google and you also want to create your own local dojo namespace, you have to consider two things. One is that you have to set the parameter baseUrl in your djConfig to “/” when loading the dojo base system:

<script type="text/javascript"
    src="/path-to-dojo-dir/dojo/dojo.js"
    djConfig="parseOnLoad: true, isDebug: false, baseUrl:'/'">
</script>

The other thing is that you have to register your module path absolute:

dojo.registerModulePath("dijit", "/absolute-path-to/myapp");

Now you’ve understood the dojo module loader, you are ready doing the next step transferring your new knowledge to a concrete django application.

Creating the reusable django app “myapp”

We assume, that you’ve already installed dojango within one of your projects. If not, you first have to follow the instructions in the getting started guide of dojango.

First you have to create your own reusable app within your django project and add a directory, where you place your javascript and css files:

cd mysite
./manage.py startapp myapp
cd myapp
mkdir media

Within the media-directory you now can place the directory that serves as your new base dojo namespace. Our recommendation is to name the namespace and the directory like your django application (in this case: myapp):

cd mysite/myapp/media
mkdir myapp

You also need to enable django to deliver the static files with your development webserver. For that you create a myapp/urls.py and add the media path to it:

import os

from django.conf.urls.defaults import patterns
from django.conf import settings

urlpatterns = []

if settings.DEBUG:
    # serving the media files for myapp / dojo (js/css/...)
    urlpatterns += patterns('',
        (r'^media/(?P<path>.*)$', 'django.views.static.serve',
            {'document_root': os.path.join(os.path.dirname(__file__), "media"),
             'show_indexes': True}),
    )

and include the app specific urls.py in your project’s urls.py, so all media-files are available below the url /myapp/media:

urlpatterns = patterns('',
    ...
    (r'^myapp/', include('dojango.urls')),
    ...
)

And also myapp must be enabled within your django project in settings.py (as with dojango):

INSTALLED_APPS = (
    ...
    'django.contrib.sites',
    'dojango',
    'myapp',
)

Defining a Dojo Namespace with Dojango

We propose a basic structure for your new namespace. You should create a file called myapp.js, where you can set all modules that should be loaded if your namespace is required and a file called _base.js that contains simple functions that you want to call directly below your namespace: something like myapp.showInfo(). This proposal was adapted from the dijit namespace:

`-- media
    `-- myapp
        |-- _base.js
        `-- myapp.js

And here is the content of our myapp.js. As stated above we need two paths to our module, an absolute and a relative path. We’ve added an extra function called dojango.setModulePath, that is accepting an absolute and a relative path, so dojo source switching is working properly within dojango (Note: the function dojango.setModulePath will soon just need an absolute path, because we can calculate the relative path. But that change will be backwards compatible, so you don’t have to worry about it now!):

// myapp.js
// defining the package name
dojo.provide("myapp.myapp");

dojo.require("dojango.dojango");
// register the path for the namespace myapp
// we need to pass a absolute and a relative url
// - a remote xd-build will use the absolute url and
// - a dojo version that is served locally is using the relative one
dojango.registerModulePath(
    "myapp",
    "/myapp/media/myapp",
    "../../../../../myapp" // relative to /dojango/media/dojo/version/dojo/dojo.js
);
// we always include our base-functions
dojo.require("myapp._base");
// if required, add more require-statements here ...

And as told above we use the _base.js for placing our main functions, that we use throughout in our app, of our namespace:

// defining the package name
dojo.provide("myapp._base");
dojo.require("dijit.Dialog");

dojo.mixin(myapp, {
    // showing a modal dialog window
    showDialog: function(title, content){
        var foo = new dijit.Dialog({title: title});
        dojo.body().appendChild(foo.domNode);
        foo.startup();

        foo.setContent(content);
        foo.show();
    }
});

Using your Dojo Namespace within a Django View

Now it is time to see everything in action. For a usage example we create a new url, a view and a template.

First mapping the url within myapp/urls.py:

...
#urlpatterns = []
urlpatterns = patterns('myapp',
    (r'^example/$', 'views.example'),
)
...

Then adding a new view to myapp/views.py:

# Create your views here.
from django.shortcuts import render_to_response
from django.template import loader, Context, RequestContext

def example(request):
    return render_to_response("myapp/example.html", context_instance=RequestContext(request))

Lastly we create the template-directory:

mkdir myapp/templates/myapp

And place our template myapp/templates/myapp/example.html there:

{% extends "dojango/base.html" %}

{% block dojango_header_extra %}
<script type="text/javascript" src="/myapp/media/myapp/myapp.js"></script>
{% endblock %}

{% block dojango_content %}
<input
   type="button"
   name="mybutton"
   value="Show dialog"
   onclick="myapp.showDialog('Awesome', 'It is working');"
/>
{% endblock %}

Start you django server via python manage.py runserver and test the example view here:

http://localhost:8000/myapp/example/

Yes. That really was a long blog article! But I hope, that this info will help you to build a nice ajaxified reusable application for django that is using dojo (and of coure dojango :-)).