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:

.. image:: _static/pylons.png
    :height: 300pt
    :width: 500pt

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:

.. image:: _static/osm.png
    :height: 300pt
    :width: 500pt

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
<http://openstreetmap.org>`_ layers.

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 of 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
            <http://www.openjsan.org/doc/a/ar/artemkhodush/>`_ [#]_, 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 Ext, OpenLayers, GeoExt and MapFish JavaScript
libraries be loaded when the web page is open 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 called when the entire HTML page is loaded and ready. 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
    <http://dev.openlayers.org/apidocs/files/OpenLayers/Map-js.html>`_ [#]_.

``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
    <http://www.geoext.org/lib/GeoExt/data/LayerStore.html>`_ [#]_.

``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
    <http://www.extjs.com/deploy/ext-2.2.1/docs/?class=Ext.Viewport>`_ [#]_.

    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 toolbar, whose items are returned by the
    ``createTbarItems`` function. See the `GeoExt.MapPanel doc
    <http://www.geoext.org/lib/GeoExt/widgets/MapPanel.html>`_ [#]_.

    The layer tree is a regular ``Ext.tree.TreePanel`` with a
    ``GeoExt.tree.LayerContainer`` as its root node. See the
    `Ext.tree.TreePanel doc
    <http://www.extjs.com/deploy/ext-2.2.1/docs/?class=Ext.tree.TreePanel>`_
    [#]_, and the `GeoExt.tree.LayerContainer doc
    <http://www.geoext.org/lib/GeoExt/widgets/tree/LayerContainer.html>`_ [#]_.



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