Create a new plugin


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

Plugins are nothing more than Django applications with an extra piece of code that integrates them into Modoboa. The 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.

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):

$ python startapp

Then, you need to register this application using the provided API. Just copy/paste the following example into the file of the future extension:

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.

    def load_initial_data(self):
        """Optional: provide initial data for your extension here."""


Once done, simply add your extension’s module name to the MODOBOA_APPS variable located inside Finally, run the following commands:

$ python migrate
$ python load_initial_data
$ python collectstatic


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 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:

from modoboa.parameters import tools as param_tools
    LEVEL, YourForm, ugettext_lazy("Title"))

Replace LEVEL by "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:

from django.dispatch import receiver
from modoboa.core import signals as core_signals

    "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")

def extra_role_permissions(sender, role, **kwargs):
   """Add permissions to the Resellers group."""
   return constants.PERMISSIONS.get(role, [])

Extending admin forms

The forms used to edit objects (account, domain, etc.) through the admin panel are composed of tabs. You can extend them (ie. add new tabs) in a pretty easy way thanks to custom signals.


To add a new tab to the account edition form, define new listeners (handlers) for the following signals:

  • modoboa.admin.signals.extra_account_forms
  • modoboa.admin.signals.get_account_form_instances
  • modoboa.admin.signals.check_extra_account_form (optional)


from django.dispatch import receiver
from modoboa.admin import signals as admin_signals

def extra_account_form(sender, user, account, **kwargs):
    return [
        {"id": "tabid", "title": "Title", "cls": MyFormClass}

def fill_my_tab(sender, user, account, **kwargs):
    return {"id": my_instance}


To add a new tab to the domain edition form, define new listeners (handlers) for the following signals:

  • modoboa.admin.signals.extra_domain_forms
  • modoboa.admin.signals.get_domain_form_instances


from django.dispatch import receiver
from modoboa.admin import signals as admin_signals

def extra_account_form(sender, user, domain, **kwargs):
    return [
        {"id": "tabid", "title": "Title", "cls": MyFormClass}

def fill_my_tab(sender, user, domain, **kwargs):
    return {"id": my_instance}