diff --git a/INSTALL b/INSTALL index c0733d7a8..29bff06b3 100644 --- a/INSTALL +++ b/INSTALL @@ -6,7 +6,7 @@ Requirements ============ - `Python version 2.6+ `_ -- `Django version 1.2+ `_ +- `Django version 1.3+ `_ - `south version 0.7+ `_ - `ldap python module `_ @@ -56,6 +56,10 @@ available: You may change its password the first time you log into Modoboa. +Finally, create the directory that will contain static content:: + + $ python manage.py collectstatic + Time zone and language ---------------------- @@ -249,6 +253,10 @@ requires a migration. 0.9: global UI refactoring, new *limits* extension and more ----------------------------------------------------------- +.. note:: + This version requires at least django 1.3. Make sure to update your + version before starting to migrate. + .. note:: Many files have been renamed/removed for this version. I recommend that you backup important files (*settings.py*, etc.) elsewhere @@ -280,6 +288,18 @@ requires a migration. 'django.contrib.auth.backends.ModelBackend', ) +#. Add ``django.contrib.staticfiles`` to ``INSTALLED_APPS`` + +#. Add the following new variables:: + + STATIC_ROOT = os.path.join(MODOBOA_DIR, 'sitestatic') + STATIC_URL = '/static/' + +#. Update the following variables (just copy/paste their new values):: + + MEDIA_ROOT = os.path.join(MODOBOA_DIR, 'media') + MEDIA_URL = '/media/' + #. **For MySQL users only**, add the following option to your database configuration:: @@ -300,7 +320,12 @@ requires a migration. $ ./manage.py syncdb --migrate -#. If you are4 using the *stats* extension, please rename the +#. Run the following command to initialize the directory that contains + static files:: + + $ ./manage.py collectstatic + +#. If you are using the *stats* extension, please rename the */static/stats* directory to */static/graphs* #. Restart the python instance(s) that serve *Modoboa* diff --git a/doc/plugin_api.rst b/doc/plugin_api.rst index 711c77613..93ee3b4ff 100644 --- a/doc/plugin_api.rst +++ b/doc/plugin_api.rst @@ -11,9 +11,9 @@ implementation provides the following possibilities: * Access and modify administrative objects (domains, mailboxes, etc.) * Register callback actions for specific events -Plugins are nothing more than Django applications using a specific -structure. The ``__init__.py`` file contains a complete description of -the plugin: +Plugins are nothing more than Django applications with an extra piece +of code that integrates them into Modoboa. Usually, the ``__init__.py`` file +will contain a complete description of the plugin: * Admin and user parameters * Observed events @@ -29,52 +29,49 @@ how you can create your own plugin. Adding a custom plugin ====================== -All Modoboa plugins must be located inside the ``extensions`` -directory. To create a new plugin, execute the following steps: +To create a new plugin, just start a new django application like +this (into modoboa's directory):: -* Run ``python manage.py startapp`` to get some basefiles for your plugin -* Move the resulting directory inside the ``extensions`` one + $ python manage.py startapp -The ``__init__.py`` file created inside your module's directory must -follow a specific structure in order to be interpreted by Modoboa. The -following functions are mandatory:: +Then, you need to register this application using the provided +API. Just copy/paste the following example into the *__init__.py* file +of the future extension:: - def init(): - """This function is called when the extension is activated. - """ - pass + from modoboa.extensions import ModoExtension, exts_pool + + class MyExtension(ModoExtension): + name = "myext" + label = "My Extension" + version = "0.1" + description = "A description" + url = "myext_root_location" # optional, name is used if not defined + + def init(self): + """This method is called when the extension is activated. + """ + pass + + def load(self): + """This method is called when Modoboa loads available and activated plugins. - def load(): - """This function is called when Modoboa loads available and activated plugins. + Declare parameters and register events here. + """ + pass + + def destroy(self): + """This function is called when a plugin is disabled from the interface. + + Unregister parameters and events here. + """ + pass - Declare parameters and register events here. - """ - pass + exts_pool.register_extension(MyExtension) - def destroy(): - """This function is called when a plugin is disabled from the interface. - - Unregister parameters and events here. - """ - pass - - def infos(): - """This function is used to populate the plugins list - available in the administration panel. - - It must return a dictionnary containing at least three - keys : "name", "version", "description" - """ - return { - "name" : "Example plugin", - "version" : "1.0", - "description" : "Example description" - } - -Once you have filled ``__init__.py``, simply add your plugin's name to -the ``INSTALLED_APPS`` variable located inside ``settings.py``. (use -the same format as other plugins). Eventually, run ``python manage.py -syncdb`` if your plugin provides custom tables. +Once done, simply add your plugin's module name to the +``INSTALLED_APPS`` variable located inside *settings.py*. Optionaly, +run ``python manage.py syncdb`` if your plugin provides custom tables +and ``python manage.py collectstatic`` to update static files. Events ====== diff --git a/urls.py b/urls.py index b35698809..835e16190 100644 --- a/urls.py +++ b/urls.py @@ -20,15 +20,14 @@ urlpatterns = patterns('', (r'^accounts/logout/$', 'modoboa.auth.views.dologout'), (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', {'packages': ('modoboa',),}), -# *loadextensions(prefix) *exts_pool.load_all(prefix) ) if settings.DEBUG: urlpatterns += patterns( - '', - (r'^static/(?P.*)$', 'django.views.static.serve', - {'document_root': settings.MEDIA_ROOT}) + url(r'^media/(?P.*)$', 'django.views.static.serve', + {'document_root': settings.MEDIA_ROOT, 'show_indexes' : True}), + url(r'', include('django.contrib.staticfiles.urls')), )