.. highlight:: python :linenothreshold: 5 .. _`talk-pluginsetup`: Creating a plugin ================= You can extend eventyay Talk with custom Python code using the official plugin API. Think of every plugin as an independent Django application living in its own python package installed like any other python module. The communication between eventyay and the plugins happens using Django's `signal dispatcher`_ feature. The core modules of eventyay expose signals which you can read about on the next pages. .. highlight:: console To create a new plugin, create a new python package which must be a valid `Django application`_ and must contain plugin metadata, as described below. You will need some boilerplate for every plugin to get started. To save you time, we created a `cookiecutter`_ template that you can use like this:: (env)$ pip install cookiecutter (env)$ cookiecutter https://github.com/fossasia/eventyay-plugin-cookiecutter This will ask you some questions and then create a project folder for your plugin. Afterwards install your plugin into eventyay:: (env)$ cd eventyay-pluginname (env)$ python -m pip install -e . If you already had it running, you'll now have to restart your eventyay development server process for it to recognise the new plugin. Your plugin should now show up in the startup message the server prints to the console. About this Documentation ------------------------ The following pages go into detail about the types of plugins supported. While these instructions don't assume that you know a lot about Eventyay, they do assume that you have prior knowledge about Django (e.g. its view layer, how its ORM works, topics covered in the Django tutorial.). Plugin metadata --------------- The plugin metadata lives inside a ``eventyayPluginMeta`` class inside your configuration class. The metadata class must define the following attributes: .. rst-class:: rest-resource-table ================== ==================== =========================================================== Attribute Type Description ================== ==================== =========================================================== name string The human-readable name of your plugin author string Your name version string A human-readable version code of your plugin. If you publish your plugin on PyPI, this should match the package version. description string A more verbose description of what your plugin does. You can use Markdown here. category string A category for your plugin, used to group it in the plugin list. Supported categories are ``FEATURE``, ``INTEGRATION``, ``CUSTOMIZATION``, ``EXPORTER``, ``RECORDING``, ``LANGUAGE``, ``OTHER`` (default). visible bool Defaults to ``True``. Setting it to ``False`` will hide the plugin from the plugin list in the event settings. ================== ==================== =========================================================== .. highlight:: python A working example would be:: from django.apps import AppConfig from django.utils.translation import gettext_lazy as _ class FacebookApp(AppConfig): name = "eventyay_facebook" verbose_name = _("Facebook") class EventyayPluginMeta: name = _("Facebook") author = _("the eventyay team") version = "1.0.0" visible = True description = _("This plugin allows you to post talks to facebook.") category = "INTEGRATION" default_app_config = "eventyay_facebook.FacebookApp" Plugin registration ------------------- .. highlight:: toml Somehow, eventyay needs to know that your plugin exists at all. For this purpose, we make use of the `entry point`_ feature of setuptools. To register a plugin that lives in a separate python package, your ``pyproject.toml`` should contain something like this:: [project.entry-points."eventyay.plugin"] eventyay_facebook = "eventyay_facebook:eventyayPluginMeta" This will automatically make eventyay discover this plugin as soon as you have installed it e.g. through ``pip``. During development, you can run ``pip install -e .`` inside your plugin source directory to make it discoverable. Make sure you do this in the same virtualenv as you're using for eventyay. Signals ------- .. highlight:: python Eventyay defines signals which your plugin can listen for. We will go into the details of the different signals in the following pages. We suggest that you put your signal receivers into a ``signals`` submodule of your plugin. You should extend your ``AppConfig`` (see above) by the following method to make your receivers available:: class FacebookApp(AppConfig): def ready(self): from . import signals # noqa You can optionally specify code that you want to execute when the organiser activates your plugin for an event in the ``installed`` method, and code to execute upon removal in the ``uninstalled`` method:: class FacebookApp(AppConfig): def installed(self, event): pass # Your code here def uninstalled(self, event): pass # Your code here The ``AppConfig`` class may also implement the method ``is_available(event)`` which checks if a plugin is available for a specific event. If not, it will not be shown on the plugin list for that event, and cannot be enabled. This method is not called on plugins with ``visibility=False``, as those are already hidden. Models ------ Often, you'll want to store additional data in your plugin. As your plugin is a Django application, you can define models in the usual way, and generate migrations for them, by running ``python -m eventyay makemigrations``. Your migrations will be applied when running ``python -m eventyay migrate`` just like any other migration. .. highlight:: console Please note that to generate your **first** migration, you will have to specify your plugin's app name explicitly in order for Django to pick it up, like this:: python -m eventyay makemigrations eventyay_facebook Views ----- Your plugin may define custom views. If you put an ``urls`` submodule into your plugin module, eventyay will automatically import it and include it into the root URL configuration with the namespace ``plugins: