# Plugins

Warning

Pootle’s plugin system is currently in an early stage of development, and may be subject to change in the future. If you have any questions or are intending to use it in your own applications you can chat with us on the Translate development channel.

You can customize or extend Pootle using plugins.

A Pootle plugin is a Django application that hooks into the core functionality in Pootle.

## Signals, providers and getters

Pootle emits `Signals` when key events happen. You can listen to these signals using a `receiver` to trigger custom behaviour. Pootle uses Django’s Signals framework for handling these types of events.

Pootle allows plugins to override the default behaviour using a `Getter` function, which are decorated with the `pootle.core.plugin.getter` decorator. Once Pootle has received a response from a plugin for a `Getter` function it stops processing any further configured functions.

Pootle allows developers to change or extend the data used by the system, by adding `Provider` functions, which are decorated with the `pootle.core.plugin.provider` decorator. With `Provider` functions Pootle will gather data from all plugins configured to provide for a given `Provider` function.

## Application file structure

- `__init__.py`
- `apps.py` - Django application configuration
- `receivers.py` - receivers for signals
- `getters.py` - getter functions
- `providers.py` - provider functions

## Creating a plugin application

Your application requires a Django application configuration

For an application named `pootle_custom` you need to add lines similar to the following in the `__init__.py`:

    default_app_config = 'pootle_custom.apps.PootleCustomConfig'

With the above configuration you should add an `apps.py`.

At a minimum this should define the `PootleCustomConfig` class with its `name` and `verbose_name`.

It can also be used to activate receivers, providers and getters. The following application configuration activates all of them for the “custom” application.

    import importlib

    from django.apps import AppConfig

    class PootleCustomConfig(AppConfig):

        name = "pootle_custom"
        verbose_name = "Pootle Custom"

        def ready(self):
            importlib.import_module("pootle_custom.receivers")
            importlib.import_module("pootle_custom.providers")
            importlib.import_module("pootle_custom.getters")

## Setting up a provider

The following is an example of providing custom `context_data` to the Pootle `LanguageView`.

Add a file called `providers.py` with the following:

    from pootle.core.delegate import context_data
    from pootle.core.plugin import provider

    from pootle_language.views import LanguageView

    @provider(context_data, sender=LanguageView)
    def provide_context_data(**kwargs):
        return dict(
            custom_var1="foo",
            custom_var2="bar")

## Setting up a getter

The following is an example of customizing the `Unit` `search_backend` for an application.

Add a file called `getters.py` with the following:

    from pootle.core.delegate import search_backend
    from pootle.core.plugin import getter

    from pootle_store.models import Unit
    from pootle_store.unit.search import DBSearchBackend

    class CustomSearchBackend(DBSearchBackend):
        pass

    @getter(search_backend, sender=Unit)
    def get_search_backend(**kwargs):
        return CustomSearchBackend

## Setting up a receiver

Pootle uses the django.core.signals module to handle events.

The following is an example of a `receiver` that emits a log warning whenever a `Store` cache is expired.

Add a file called `receivers.py` with the following code:

    import logging

    from django.core.signals import receiver

    from pootle.core.signals import cache_cleared
    from pootle_store.models import Store

    @receiver(cache_cleared, sender=Store)
    def handle_cache_cleared(**kwargs):
        logging.warning(
            "Store cache cleared: %s"
            % kwargs["instance"].pootle_path)