== The Site object ==
Every modu application is configured by creating a `Site` class that can be discovered by modu at request time. A very basic `Site` class might look something like this:

{{{
#!python
class Site(object):
    classProvides(plugin.IPlugin, app.ISite)
    
    def initialize(self, application):
        application.base_domain = 'localhost'
        application.base_path = '/modu'
        application.activate('/', index.Resource)
}}}

The `initialize()` method is called the first time a URL for a particular site is loaded.

== The Application object ==

A newly instantiated `Application` object is passed to `Site::initialize()`, where we can set any static site configuration variable needed. A number of standard config variables exist, but projects can create new ones as desired.

One an application object is created, it is immutable for the lifetime of the server process it's running under. When unit testing, `Application::make_immutable()` is often omitted as a convenience by those who know what they're doing.

    '''base_domain'''::
    Default: `'localhost'`::
        The base domain is the domain that this application will be loaded for.

    '''base_path'''::
    Default: `'/'`::
        The base path is where the root modu resource is located.

    '''db_url'''::
    Default: `'MySQLdb://modu:modu@localhost/modu'`::
        A specially constructed URL representing the database connection details.

    '''session_class'''::
    Default: `session.DbUserSession`::
        The default session class. Set to None to disable sessions.

    '''session_cookie_params'''::
    Default: `{'Path':'/'}`::
        The default paramaters for the created session cookie.

    '''initialize_store'''::
    Default: `True`::
        Should a store object be created by default?

    '''webroot'''::
    Default: `'webroot'`::
        If a path is not found within the URL Tree (i.e., there is no Resource at a given URL), the path is translated to the webroot, which, if a relative path, is appended to the application's `approot`.

    '''debug_session'''::
    Default: `False`::
        If True, display debug information when a session is loaded or saved.

    '''debug_store'''::
    Default: `False`::
        If True, display queries when objects are loaded or saved.

    '''enable_anonymous_users'''::
    Default: `True`::
        If the current req.user is not a logged-in user, create an AnonymousUser instance instead of using None

    '''disable_session_users'''::
    Default: `False`::
        If True, don't login users based on their session information.

    '''disable_message_queue'''::
    Default: `False`::
        If True, disable creation of the session-based message queue.

    '''magic_mime_file'''::
    Default: `None`::
        If defined, specify an additional location for the magic mime file. For example, on Mac OS X with Apache 2, this should be set to `/etc/apache2/mime.types`

    '''tree'''::
        The URL tree that is populated by the Site class

    '''site'''::
        The Site class used to create this Application

Apart from configuration variables, the application object also manages the `URLNode` tree of resources that make up your site. A new resource is added by providing the path, a `Resource` class and any arguments to `Application::activate()`, usually from inside a `Site::initialize()` method.

{{{
#!python
def initialize(self, application):
    # ...other configuration code here
    application.activate('/', index.Resource)
    application.activate('/pages', page.Resource, 'example.com')
    application.activate('/admin', resource.AdminResource,
        default_path    = 'admin/listing/page', 
        itemdef_module  = myproject.itemdefs
    )
}}}

In this example, a request for http://example.com/admin would instantiate the `AdminResource` class with the provided `default_path` and `itemdef_module` keyword arguments. We'll talk more about the admin resource later on.

A nice side-effect of instantiating resources at request time is that you can feel free to use member attributes to hold references to data during the content generation process. Since the object will be disposed of after the request is over, you're safe from influencing any other requests.

== The Request object ==

A single `Request` object is created as a representation of an HTTP request, and is passed around a modu application through the lifetime of a request. It contains a series of environment variables describing the current request, and also holds on to a number of modu-specific variables, as well as outgoing headers for the HTTP response.

First and foremost, Request objects hold the key-value pairs supplied by the WSGI environment. These are basically similar to the variables defined by the CGI standard:

    || REQUEST_METHOD  ||  CONTENT_LENGTH  ||
    || SCRIPT_NAME     ||  SERVER_NAME     ||
    || PATH_INFO       ||  SERVER_PORT     ||
    || QUERY_STRING    ||  SERVER_PROTOCOL ||
    || CONTENT_TYPE    ||  HTTP_*          ||

The last item (HTTP_*) represents the standard HTTP headers such as HTTP_CONTENT_LENGTH and others.

Also included are the WSGI-specific variables such as:

    || wsgi.version    ||  wsgi.multithread   ||
    || wsgi.url_scheme ||  wsgi.multiprocess  ||
    || wsgi.input      ||  wsgi.run_once      ||
    || wsgi.errors     ||                     ||

More information on these variables can be found in the WSGI spec:

    http://www.python.org/dev/peps/pep-0333

Finally, a number of modu-specific variables are created:

    '''modu.app'''::
        The current `Application` object, containing the configuration variables for this site/application.

    '''modu.approot'''::
        The main modu application directory. This is dynamically detected as being 2 directory levels above the discovered modu site configuration file.

    '''modu.path'''::
        The URL path *after* the subpath where this application is located; for example, if an application's base path is /myapp, a request to /myapp/root would result in a modu.path of '/root'.

    '''modu.pool'''::
        The default database connection, if available.

    '''modu.store'''::
        The default `Store` object, connected through '''modu.pool'''

    '''modu.session'''::
        The current `Session`, if available.

    '''modu.user'''::
        The current logged-in user, if available. Can also be an `AnonymousUser` object, or `None`.

    '''modu.messages'''::
        An interface to server user messages and errors, saves temporary data in session.

    '''modu.data'''::
        Currently posted form data

    '''modu.content'''::
        An interface for storing HTML header content, allowing modu code to add style sheets or javascript at any time.

All of the modu.* variables can be accessed as attributes on the `Request` object (e.g., req.app, req.store. req.pool). 

Additionally, the `Request` object provides the following attributes:

    '''rsrc'''::
        The currently selected `Resource` object, if available

    '''prepath'''::
        A list of path elements representing consisting of the path TO the current `Resource` within modu; if 'modu.path' is /one/two/three, and the current `Resource` is activated at /one, prepath will be `['one']`

    '''postpath'''::
        A list of path elements representing consisting of the path FROM the current `Resource` within modu; if 'modu.path' is /one/two/three, and the current `Resource` is activated at /one, prepath will be `['two', 'three']`

    '''response_headers'''::
        A list of tuples representing the HTTP response headers to be returned.

=== Error Logging ===

When developing modu applications, users are encouraged to use the built-in, Twisted-based web server to run their applications. In this situation, any number of methods are available for logging to the console (or error log), but it's generally as simple as issuing a 'print' statement.

If you want to log properly in any environment, you'll want to use `Request::log_error()` to make a proper WSGI log line. This method is a convenience function that performs a write (with line-endings) to the stream that's kept in the Request object as 'wsgi.errors' -- remember, modu `Request` objects support all the keys passed in the WSGI environment dictionary.

=== JIT Variables ===

The modu.* variables 'pool', 'store', 'session', 'user', and 'messages' are "Just In Time" variables, and are only populated when first requested.

These variables behave much the same way as regular request variables, but there's one catch. Checking containment of a JIT variable (e.g., `'modu.session' in req`) will not instantiate that variable if it hasn't been used yet, but will still return `True`.

Neither will using `req.get()` instantiate a JIT variable. Only using the `req['modu.session']` or `req.session` syntax will populate the variable on-demand.
