Module 2 - Creating Application

In this module you will learn how to create a MapFish application. You will study the structure of a MapFish application, and the code the MapFish framework generates for you when creating a MapFish application.

Generating the application

Generating the base

To create a MapFish application use:

<env> C:\MapFish> paster create -t mapfish MapFishApp

MapFishApp is the name of the MapFish application you’re creating, you can pick any name of your choice. We’ll assume that you choose MapFishApp in the rest of the document.

When asked what template engine to use answer mako, which is the default. When asked if SQLAlchemy 0.5 configuration is to be included, answer True, as your MapFish application will include web services relying on database tables.

You should now have a folder named MapFishApp. This folder contains your application files, at this point mainly Python files.

Now is the time to check that your MapFish application works. For this go into the MapFishApp folder and start the application:

<env> C:\MapFish>cd MapFishApp
<env> C:\MapFish\MapFishApp>paster serve development.ini

This command starts your application in the Paster web server, which is a pure-Python web server, commonly used during development.

Open http://localhost:5000 in your web browser, you should get the default page:

_images/pylons.png

Installing the MapFish JavaScript toolbox

You are now going to install the MapFish JavaScript toolbox in your application. This toolbox includes:

  • the Ext, OpenLayers, GeoExt and MapFish Client JavaScript libraries,
  • a sample JavaScript application based on those libraries,
  • a build profile for minifying the JavaScript code of this sample application,
  • a JavaScript testing framework, with a test example

Enter Ctrl+C to stop the Paster server and proceed with these commands:

<env> C:\MapFish\MapFishApp>cd ..
<env> C:\MapFish> paster create -t mapfish_client MapFishApp

When asked whether to overwrite index.html answer y. This will overwrite the index.html page you saw in the last section by the one provided by the mapfish_client template.

Start the application again:

<env> C:\MapFish>cd MapFishApp
<env> C:\MapFish\MapFishApp>paster serve --reload development.ini

Note

Note the use of the --reload switch. This switch makes the Paste server monitor all Python modules used by the MapFishApp application and reload itself automatically if any of them is modified or if new modules are created. This is especially useful during development.

Open or reload http://localhost:5000 in your web browser, you should now get the default user interface:

_images/osm.png

This default user interface is composed of: a map, a toolbar above the map with tools acting on the map, and a layer tree for controlling the visibility of layers. The map itself is composed of two OpenStreetMap base layers (Mapnik and Tiles@Home).

The default user interface is provided to the application developer as an example. The application developer is free to build on it, or delete it to write his own if he wants.

As mentioned at the begining of this section, the JavaScript toolbox installed in the MapFish application comes with a JavaScript testing framework. We clearly see one of the goals of MapFish here: freeing the Application developer from tedious tasks and making him more productive in the development of high-quality, tested code. A test example is provided, to execute it load http://localhost:5000/tests in your browser.

Studying the application

The following sub-sections give you a quick tour through the folders and files of your MapFish application. Take some time to browse those folders and files, so you get a sense of how the application is structured.

Global structure

The application’s main folder, MapFishApp, contains:

development.ini
This is the application’s configuration file. This file includes things like the IP address and TCP port the server should listen on, the database connection string, etc.
layers.ini
This is where the application developer gives information about web services to be generated by the framework. We’ll get back to this file in the Creating Web Services module later in the document.
jsbuild
This folder contains the JavaScript build profile for the default user interface. We’ll come back to that in the Building JavaScript module later in the document.
setup.cfg and setup.py
These files control various aspects of how the MapFish application is packaged when you distribute it.

mapfishapp

This is the main application folder, its name depends on the application name given as the argument to the paster create command. The main sub-folders of this folder are: controllers, model, lib, config, tests, templates, and public.

controllers
The controllers folder contains the application controllers. The controllers are the components that handle HTTP requests and send HTTP responses. They often interact with the model and templates code.
model
The model folder is where the database model is configured. This is basically where tables and relations are defined.
lib
The lib folder includes Python code shared by different controllers, and third-party code.
config
The config folder includes Python code generated by the framework and exposed to the application for customization.
tests
The tests folder is where you can add Python automated tests for the application.
templates
The templates folder is where view templates are stored. Note that we won’t write templates as part of this workshop, as the HTML rendering will mostly be done client side.

public

The public folder includes the application’s static files, i.e. HTML, CSS, JavaScript files, etc. Most of this folder was populated when you installed the JavaScript toolbox with paster create -t mapfish_client. The main files and folders inside this folder are: index.html, mfbase, app, and tests.

index.html
The index.html file is the user interface’s HTML page. This is where the JavaScript code is loaded.
mfbase
The mfbase folder contains the MapFish JavaScript toolbox librairies, namely Ext, OpenLayers, GeoExt and MapFish Client.
app
The app folder contains application-specific files. It js sub-folder includes the JavaScript code of the default user interface.
tests
The tests folder is where the application developer can put its JavaScript tests. The folder includes the JavaScript testing framework, Test.AnotherWay [1], and a test example.

User interface

Let’s now review the various files that make up the default user interface (i.e. the web page with the OSM layers).

Edit the index.html file and look up these lines:

<script type="text/javascript" src="mfbase/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="mfbase/ext/ext-all-debug.js"></script>
<script type="text/javascript" src="mfbase/openlayers/lib/OpenLayers.js"></script>
<script type="text/javascript" src="mfbase/geoext/lib/GeoExt.js"></script>
<script type="text/javascript" src="mfbase/mapfish/MapFish.js"></script>

These <script> tags make the ExtJS, OpenLayers, GeoExt and MapFish JavaScript libraries be loaded when the web page is openned in the browser. These are the versions of the libraries where the JavaScript code is not minified. Again, we’ll talk about JavaScript minification in the Building JavaScript module.

The lines:

<script type="text/javascript" src="app/js/mapfishapp_layout.js"></script>
<script type="text/javascript" src="app/js/mapfishapp_init.js"></script>

in the index.html take care of loading the application-specific JavaScript code. As you have noticed the JavaScript code of the default user interface is composed of two files. The application developer is free to add more files if needed.

The mapfishapp_init.js file represents the entry point.

/*
 * @include mapfishapp_layout.js
 */

Ext.namespace("mapfishapp");

(function() {
    // run mapfishapp.layout.init() when the page
    // is ready
    Ext.onReady(function() {
        mapfishapp.layout.init()
    });
})();

This file just creates the application namespace, and registers a callback to be run when the entire HTML page and its components are loaded. The callback is registered using the Ext.onReady function; we infer from the namespace of the function that the function is provided by the Ext library. Using Ext.onReady is typical in Ext-based applications.

The mapfishapp_layout.js file is where the page layout is defined. This file contains private functions, i.e. functions that cannot be called from outside the mapfishapp.layout module, and the init public function, which is the function that was passed to the Ext.onReady function.

Let’s review what the mapfish.layout module’s functions do.

createMap
This function creates the map, which is an instance of OpenLayers.Map. See the OpenLayers.Map doc [2].
createLayers
This function creates the OSM layers and return them.
createLayerStore
This function creates a GeoExt.data.LayerStore object with the map and layers passed as arguments. A GeoExt.data.LayerStore is necessary for creating a map panel. See the GeoExt.data.LayerStore doc [3].
createTbarItems
This function create and return toolbar items. Here the toolbar items are GeoExt.Action objects. We’ll go back to GeoExt.Action in the Customize the Application module.

init

This function starts by calling the createMap, createLayers, and createLayerStore functions to actually create the map, layers, and layer store.

It then creates an Ext.Viewport, which is a graphical component representing the entire browser viewport. The viewport contains other grahical components: its items. The viewport here contains two items, a map panel and a layer tree panel. See the Ext.Viewport doc [4].

The map panel, which is a GeoExt object, is configured with the map and the layer store objects. The map panel is also a container, with one item: the zoom slider. The map panel has a top toolbar, whose items are returned by the createTbarItems function. See the GeoExt.MapPanel doc [5].

The layer tree is a regular Ext.tree.TreePanel with a GeoExt.tree.LayerContainer as its root node. See the Ext.tree.TreePanel doc [6], and the GeoExt.tree.LayerContainer doc [7].

[1]http://www.openjsan.org/doc/a/ar/artemkhodush/
[2]http://dev.openlayers.org/apidocs/files/OpenLayers/Map-js.html
[3]http://www.geoext.org/lib/GeoExt/data/LayerStore.html
[4]http://www.extjs.com/deploy/ext-2.2.1/docs/?class=Ext.Viewport
[5]http://www.geoext.org/lib/GeoExt/widgets/MapPanel.html
[6]http://www.extjs.com/deploy/ext-2.2.1/docs/?class=Ext.tree.TreePanel
[7]http://www.geoext.org/lib/GeoExt/widgets/tree/LayerContainer.html