Registration plugins

Open Forms has a plugin system for the registrations module. The registrations module is invoked when a form submission is completed, and is responsible for persisting the form data to the configured backend.

Developing plugins

Every possible backend can be implemented as a plugin, and registered with Open Forms.

Registering the plugin makes it available for content-editors to select as a registration backend for a form.

Implementation

A plugin is nothing more than a callable, most often a plain Python function. It must adhere to the following function signature:

from openforms.submissions.models import Submission


def plugin(submission: Submission, options: dict) -> dict | None:
    # do stuff

The function body is of course up to you to interact with the registration backend.

Each backend can require additional configuration/options that is required for the implementation. This is specified as a rest_framework.serializers.Serializer:

from zgw_consumers.models import Service, APITypes


class PluginOptions(serializers.Serializer):
    zaaktype = serializers.URLField()
    zaken_api = serializers.PrimaryKeyRelatedField(
        queryset=Service.objects.filter(api_type=APITypes.zrc)
    )

Plugin developers have full control over these serializers.

The serializer is specified during plugin registration, using the @register decorator syntax:

from ...registry import register


@register("unique-key", "Human readable name", configuration_options=PluginOptions)
def plugin(submission: Submission, options: dict) -> dict:
    ...

The return value of the callback is saved on the submission as backend result/log. If this is not JSON-serializable, you can specify a serializer for this as well:

from ...registry import register


@register(
    "unique-key",
    "Human readable name",
    configuration_options=PluginOptions,
    backend_feedback_serializer=BackendFeedbackSerializer,
)
def plugin(submission: Submission, options: dict) -> dict:
    ...

Registration failure

If the registration fails for whatever reason, then your plugin should raise openforms.registrations.exceptions.RegistrationFailed. This will mark the submission with a failed state, making it possible to handle these failures.

The submission handler extracts the traceback, so you should ideally raise this exception from the root exception to include the full traceback:

try:
    ...  # do plugin stuff
except Exception as exc:
    raise RegistrationFailed from exc

Public Python API

Plugin base class

class openforms.registrations.base.BasePlugin(identifier: str)
camel_case_ignore_fields = None

Iterable of JSON keys to ignore when converting between snake_case/camelCase.

configuration_options

A serializer class describing the plugin-specific configuration options.

A plugin instance is the combination of a plugin callback and a set of options that are plugin specific. Multiple forms can use the same plugin with different configuration options. Using a serializer allows us to serialize the options as JSON in the database, and de-serialize them into native Python/Django objects when the plugin is called.

alias of openforms.registrations.base.EmptyOptions

get_custom_templatetags_libraries() list[str]

Return a list of custom templatetags libraries that will be added to the ‘sandboxed’ Django templates backend.

get_variables() list[FormVariable]

Return the static variables for this registration plugin.

pre_register_submission(submission: Submission, options: dict) PreRegistrationResult

Perform any tasks before registering the submission

For plugins where the registration backend does not generate a reference number, no need to implement this method.

class openforms.registrations.base.PreRegistrationResult(reference: str = '', data: Optional[dict] = None)

Encapsulate the submission reference and any intermediate result from pre-registration.

Module documentation

The openforms.registrations package provides the persistence backends for submissions.

Once a form is submitted (‘completed’) by an end-user, a openforms.submissions.models.Submission instance is available holding all the submitted data.

This data needs to be forwarded to the appropriate systems - it could be that a Zaak has to be created, or just an e-mail sent somewhere, or anything else. This package provides a public Python API to trigger this mechanism, where each individual plugin implements said appropriate system.

The registered plugins all have their own specific configuration and quirks, and we will expose this to the form designers / editors. We couple a single form object to a particular backend that needs to handle it.