= Working with modu Site Configurations =

Site configuration in modu can seem a little daunting at first, especially if your introduction to it is a large-scale project with many different deployment targets. The best way to understand is to start with an extremely simple site config:

{{{
#!python
class Site(object):
	classProvides(plugin.IPlugin, app.ISite)
	
	def initialize(self, application):
		application.base_domain = 'localhost'
		application.db_url = 'MySQLdb://myproject:mypassword@localhost/myproject'
		
		import myproject
		compiled_template_root = os.path.abspath(os.path.join(os.path.dirname(myproject.__file__), '../var'))
		if(os.path.exists(compiled_template_root)):
			application.compiled_template_root = compiled_template_root
		
		application.activate('/path', ResourceClass, arg1, arg2, arg3)
}}}

== What is an ISite? ==
Site configurations are simply classes that implement the '''twisted.plugin.IPlugin''' and '''modu.app.ISite''' interfaces. They're placed in the modu.sites package almost magically; just create a `modu/sites/whatever.py` file somewhere in your classpath, and it will be found by the Twisted plugin system.

Generally, you will create these configs in directories that will only be part of the path when your application is run. For example, mod_python automatically adds the directory of the selected handler to the system path; if you place a `modu/sites` package in that directory, it will be available to any modu instances running inside mod_python (and why are you using mod_python anyways? tsk. tsk. tsk).

A more likely scenario is that you'll explicitly set the `MODU_PATH` environment variable for the applications, which is automatically added to your path. In the case of the Twisted.Web deployment option, the current directory (controlled by the twistd -d switch) is automatically used if `MODU_PATH` isn't defined.

== Configuring Your Application ==
In modu, there's only two different kinds of configuration variables: hardcoded values that can be assigned globally for the entire application, and values that can be different depending on the particular request being handled. Each type of configuration option has its own method:

'''def initialize(self, application):'''
    This is where most configuration should occur. `initialize()` is only called the first time the application is launched, but does not receive a request object.

'''def configure_request(self, req):'''
    Usually this function is used to store user- or request-specific configuration data, but it may be used for global variable settings. For example, since modu is essentially a pure-WSGI app, often there are environment states that are unknown until the first request is made.
    Keep in mind that this function will be called on every request, so you want to be wary of expensive configuration procedures.

== Configuration Variables ==
There are a number of predefined configuration variables that are relevant for all modu projects. Technically, these should all be treated as read-only objects -- more on this later.

|| '''variable''' || '''default''' || '''description''' ||
|| base_domain || `'localhost'` || The domain name that will load this application ||
|| base_path || `'/'` || The path at which this application is found (affects pre/postpath request variables) ||
|| db_url || `'MySQLdb://modu:modu@localhost/modu'` || The database connection string for the default connection ||
|| session_class || `session.DbUserSession` || The default session class ||
|| session_cookie_params || `{'Path':'/'}` || Cookie settings for the session ||
|| initialize_store || `True` || If False, do not open a default database connection ||
|| webroot || `'webroot'` || An absolute path or relative path from the approot that contains static files. ||
|| debug_session || `False` || Print session debug info ||
|| debug_store || `False` || Print store debug info ||
|| enable_anonymous_users || `True` || When the session is authenticated, should req.user be None or an AnonymousUser instance? ||
|| disable_session_users || `False` || Should we attempt to load a user based on the user_id saved with the session? ||
|| disable_message_queue || `False` || Should we disable creation of the session-resident message queue? ||
|| magic_mime_file || `None` || Path to the system mimetypes file, to supplement internal Python mimetypes. ||
|| tree || ''current resource tree'' || The tree of resource objects used in this application. ||
|| site || ''current site object'' || The site object that was used to create this application instance. ||
|| approot || ''location of modu.sites directory.'' || The top-level directory for the application, where the `template` directory is located. ||

Additionally, applications can define their own variables on the application object.

=== Application Caveats ===
Although you can modify the application object during application runtime (for example, through the 'modu.app' key on the Request object), there are a number of caveats that are involved in such an approach. First of all, if you're running in a multithreaded environment (like the default `twistd` deployment method), you'll need to delegate access to the application object in some way, such as a semaphore. Conversely, if you're using something like a prefork version of Apache with mod_wsgi, there's nothing you can do to propagate your changes to the other processes.

If you need more dynamic capabilities for your configuration variables, you should probably consider saving them in the Request object, which is always safe to edit, since it only exists for the lifetime of the request itself.