Skip to content

Lifecycle Hooks

FastPluggyBaseModule exposes two startup hooks. Both receive the FastPluggy instance via automatic injection.

Call order

FastPluggy.__init__()
  └─ load_app()
       ├─ discover_plugins()
       ├─ initialize_plugins_in_order()
       ├─ configure_templates()
       ├─ execute_all_module_hook("after_setup_templates")  ← hook 1
       └─ execute_all_module_hook("on_load_complete")       ← hook 2

Both hooks support sync and async implementations.


after_setup_templates(self, fast_pluggy)

Called after the Jinja2 environment is built. Use it to:

  • Add custom template filters or globals
  • Create parent sidebar menu items (menu items registered with @menu_entry need their parent to exist first)
def after_setup_templates(self, fast_pluggy):
    fast_pluggy.menu_manager.create_parent_item(
        name="my_plugin",
        label="My Plugin",
        icon="ti ti-star",
        type="main",
        position=20,
    )
    # custom Jinja2 filter
    fast_pluggy.templates.env.filters["my_filter"] = my_filter_fn

on_load_complete(self, fast_pluggy)

Called last, after every plugin has been initialized. Use it to:

  • Register topbar actions
  • Read other plugins' globals from GlobalRegistry
  • Set up cross-plugin integrations
from fastpluggy.core.global_registry import GlobalRegistry
from fastpluggy.core.topbar import TopbarAction

def on_load_complete(self, fast_pluggy):
    GlobalRegistry.extend_globals('topbar_actions', items=[
        TopbarAction(id='my-topbar', icon='ti ti-star', tooltip='My Plugin',
                     position=20, module_name=self.module_name)
    ])

Async hooks

Both hooks can be async def. The framework detects coroutines and awaits them correctly:

async def on_load_complete(self, fast_pluggy):
    await some_async_setup()