--- title: plugin development guide for modoboa description: Discover how to develop a plugin for modoboa to extend functionnalities head: - - meta - name: 'keywords' content: 'modoboa, plugin, extension, api, navigation, Django signals' --- # Create a new plugin ## Introduction Modoboa offers a plugin API to expand its capabilities. The current implementation provides the following possibilities: - Expand navigation by adding entry points to your plugin inside the GUI - Access and modify administrative objects (domains, mailboxes, etc.) - Register callback actions for specific events ::: tip Plugins are nothing more than Django applications with an extra piece of code that integrates them into Modoboa. ::: The `modo_extension.py` file will contain a complete description of the plugin: - Admin and user parameters - Custom menu entries The communication between both applications is provided by [Django signals](https://docs.djangoproject.com/en/5.2/topics/signals/). The following subsections describe the plugin architecture and explain how you can create your own. ## The required glue To create a new plugin, just start a new django application like this (into Modoboa's directory): ```shell $ python manage.py startapp ``` Then, you need to register this application using the provided API. Just copy/paste the following example into the `modo_extension.py` file of the future extension: ```python from modoboa.core.extensions import ModoExtension, exts_pool class MyExtension(ModoExtension): """My custom Modoboa extension.""" name = "myext" label = "My Extension" version = "0.1" description = "A description" url = "myext_root_location" # optional, name is used if not defined def load(self): """This method is called when Modoboa loads available and activated plugins. Declare parameters and register events here. """ pass def load_initial_data(self): """Optional: provide initial data for your extension here.""" pass exts_pool.register_extension(MyExtension) ``` Once done, simply add your extension's module name to the `MODOBOA_APPS` variable located inside `settings.py`. Finally, run the following commands: ```shell $ python manage.py migrate $ python manage.py load_initial_data $ python manage.py collectstatic ``` ### Parameters A plugin can declare its own parameters. There are two levels available: * `Global` parameters: used to configure the plugin, editable inside the *Admin > Settings > Parameters* page * `User` parameters: per-user parameters (or preferences), editable inside the *Options > Preferences* page #### Playing with parameters Parameters are defined using [Django forms](https://docs.djangoproject.com/en/1.9/topics/forms/) and Modoboa adds two special forms you can inherit depending on the level of parameter(s) you want to add: * `modoboa.parameters.forms.AdminParametersForm`: for general parameters * `modoboa.parameters.forms.UserParametersForm`: for user parameters To register new parameters, add the following line into the `load` method of your plugin class: ```python from modoboa.parameters import tools as param_tools param_tools.registry.add(LEVEL, YourForm, ugettext_lazy("Title")) ``` Replace: * `LEVEL` (str): `"global"` or `"user"`. ### Custom role permissions Modoboa uses Django's internal permission system. Administrative roles are nothing more than groups (`Group` instances). An extension can add new permissions to a group by listening to the `extra_role_permissions` signal. Here is an example: ``` python from django.dispatch import receiver from modoboa.core import signals as core_signals PERMISSIONS = { "Resellers": [ ("relaydomains", "relaydomain", "add_relaydomain"), ("relaydomains", "relaydomain", "change_relaydomain"), ("relaydomains", "relaydomain", "delete_relaydomain"), ("relaydomains", "service", "add_service"), ("relaydomains", "service", "change_service"), ("relaydomains", "service", "delete_service") ] } @receiver(core_signals.extra_role_permissions) def extra_role_permissions(sender, role, **kwargs): """Add permissions to the Resellers group.""" return constants.PERMISSIONS.get(role, []) ```