Hide navigation sidebar
Hide table of contents sidebar
Skip to content
Back to top
View this page
Toggle table of contents sidebar

# Extension plugins

Type | `betty.project.extension.Extension`
Repository | `betty.project.extension.EXTENSION_REPOSITORY`

Extensions are core application components, and can be enabled and configured per project. An extension can do many things, such as loading new or expanding existing ancestry data, or generating additional content for your site.

## Creating an extension

1. Create a new class that extends `betty.project.extension.Extension` and implements the abstract methods, for example:

       from typing import override
       from betty.project.extension import Extension

       class MyExtension(Extension):
         @override
         @classmethod
         def plugin_id(cls) -> str:
             return "my-module-my-extension"

         # Implement remaining abstract methods...
         ...

2. Tell Betty about your extension by registering it as an entry point. Given the extension above in a module `my_package.my_module`, add the following to your Python package:

pyproject.toml

    [project.entry-points.'betty.extension']
    'my-module-my-extension' = 'my_package.my_module.MyExtension'

setup.py

    SETUP = {
        'entry_points': {
            'betty.extension': [
                'my-module-my-extension=my_package.my_module.MyExtension',
            ],
        },
    }
    if __name__ == '__main__':
        setup(**SETUP)

## Asset management

Extensions can enable asset management to provide translations, templates, and more, by overriding `betty.project.extension.Extension.assets_directory_path()` to return the path on disk where the extension’s assets are located. This may be anywhere in your Python package.

    from typing import override
    from betty.project.extension import Extension

    class MyExtension(Extension):
        @override
        @classmethod
        def assets_directory_path(cls) -> Path | None:
            # A directory named "assets" in the same parent directory as the current Python file.
            return Path(__file__).parent / 'assets'

       # Implement remaining abstract methods...
       ...

## Event handling

Extensions can act on events by overriding `betty.project.extension.Extension.register_event_handlers()`. Any number of events may be handled, and any number of handlers may be registered per event. Handlers are invoked in their order of registration.

    from typing import override
    from betty.load import LoadAncestryEvent
    from betty.project.extension import Extension

    def _load_ancestry(event: LoadAncestryEvent) -> None:
        # Do what this function should do...
        ...

    class MyExtension(Extension):
        @override
        @classmethod
        def register_event_handlers(self, registry: EventHandlerRegistry) -> None:
            registry.add_handler(LoadAncestryEvent, _load_ancestry)

       # Implement remaining abstract methods...
       ...

### See also

Read more about event dispatching and Betty’s built-in events at Event dispatching.

## Dependencies

Important

Any dependencies on other Python packages must be declared by your extension’s Python package.

Extensions have fine-grained control over which other extensions they require, and the order in which they appear in the extension dependency tree:

`betty.project.extension.Extension.depends_on()`

  Declare required other extensions. This ensures those extensions are enabled and appear before your extension in the extension dependency tree.

`betty.project.extension.Extension.comes_after()`

  Declare other extensions that are not required, but if they are enabled, then your extension will appear after them in the extension dependency tree.

`betty.project.extension.Extension.comes_before()`

  Declare other extensions that are not required, but if they are enabled, then your extension will appear before them in the extension dependency tree.

## Optional functionality

Extensions can optionally provide the following functionality:

`betty.project.extension.ConfigurableExtension`

  Enable configuration management for the extension.

`betty.project.extension.Theme`

  Mark the extension as being a theme, e.g. an extension that determines the overall look and feel of a site.

`betty.html.CssProvider`

  Add additional CSS files to generated pages.

`betty.html.JsProvider`

  Add additional JavaScript files to generated pages.

`betty.jinja2.Jinja2Provider`

  Integrate the extension with Jinja2.

## See also

Read more about how to use extensions and Betty’s built-in extensions at Extensions.