Files
modoboa/doc-ng/contributing/plugin_api.md
T

144 lines
4.2 KiB
Markdown

---
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, [])
```