Search documentation of phoenix_kit

# PhoenixKit.Module behaviour (phoenix_kit v1.7.87)

Copy Markdown View Source

Behaviour for PhoenixKit feature modules (internal and external).

Any module that implements this behaviour can register itself with PhoenixKit's tab registry, permission system, supervisor tree, and route system.

## Usage

    defmodule PhoenixKitHelloWorld do
      use PhoenixKit.Module

      @impl true
      def module_key, do: "hello_world"

      @impl true
      def module_name, do: "Hello World"

      @impl true
      def enabled?, do: PhoenixKit.Settings.get_boolean_setting("hello_world_enabled", false)

      @impl true
      def enable_system do
        PhoenixKit.Settings.update_boolean_setting_with_module("hello_world_enabled", true, "hello_world")
      end

      @impl true
      def disable_system do
        PhoenixKit.Settings.update_boolean_setting_with_module("hello_world_enabled", false, "hello_world")
      end

      @impl true
      def permission_metadata do
        %{
          key: "hello_world",
          label: "Hello World",
          icon: "hero-hand-raised",
          description: "A demo module"
        }
      end

      @impl true
      def admin_tabs do
        [%PhoenixKit.Dashboard.Tab{
          id: :admin_hello_world,
          label: "Hello World",
          icon: "hero-hand-raised",
          path: "hello-world",
          priority: 640,
          level: :admin,
          permission: "hello_world",
          match: :prefix,
          group: :admin_modules
        }]
      end
    end

## Required Callbacks

- `module_key/0` - Unique string key (e.g., `"tickets"`, `"billing"`)
- `module_name/0` - Human-readable display name
- `enabled?/0` - Whether the module is currently enabled
- `enable_system/0` - Enable the module system-wide
- `disable_system/0` - Disable the module system-wide

## Optional Callbacks

All optional callbacks have sensible defaults provided by `use PhoenixKit.Module`:

- `get_config/0` - Module stats/config map (default: `%{enabled: enabled?()}`). The default calls `enabled?()` which may hit the database. External modules with expensive config should override this with a cached implementation.
- `permission_metadata/0` - Permission key, label, icon, description (default: `nil`)
- `admin_tabs/0` - Admin navigation tabs (default: `[]`)
- `settings_tabs/0` - Settings subtabs (default: `[]`)
- `user_dashboard_tabs/0` - User-facing dashboard tabs (default: `[]`)
- `children/0` - Supervisor child specs (default: `[]`)
- `route_module/0` - Module providing route macros (default: `nil`)
- `version/0` - Module version string (default: `"0.0.0"`)
- `migration_module/0` - Module implementing versioned migrations (default: `nil`). When set, `mix phoenix_kit.update` will automatically run this module's migrations alongside the core PhoenixKit migrations.

## Summary

### Types

permission_meta()

Permission metadata for the module

### Callbacks

admin_tabs()
children()
css_sources()

Returns the OTP app name for Tailwind CSS source scanning.

disable_system()
enable_system()
enabled?()
get_config()
migration_module()
module_key()
module_name()
permission_metadata()
required_modules()
route_module()
settings_tabs()
user_dashboard_tabs()
version()

## Types

# permission_meta()

    @type permission_meta() :: %{
      key: String.t(),
      label: String.t(),
      icon: String.t(),
      description: String.t()
    }

Permission metadata for the module

## Callbacks

# admin_tabs()

(optional)

    @callback admin_tabs() :: [PhoenixKit.Dashboard.Tab.t()]

# children()

(optional)

    @callback children() :: [Supervisor.child_spec() | module() | {module(), term()}]

# css_sources()

(optional)

    @callback css_sources() :: [String.t()]

Returns the OTP app name for Tailwind CSS source scanning.

The installer uses this to generate the correct `@source` directive in the parent app's `app.css`. It automatically resolves the right path based on whether the dep is installed from Hex (`deps/`) or as a path dep.

## Example

    def css_sources, do: [:phoenix_kit_publishing]

Headless modules (no templates) can skip this callback — the default is `[]`.

# disable_system()

    @callback disable_system() :: :ok | {:ok, term()} | {:error, term()}

# enable_system()

    @callback enable_system() :: :ok | {:ok, term()} | {:error, term()}

# enabled?()

    @callback enabled?() :: boolean()

# get_config()

(optional)

    @callback get_config() :: map()

# migration_module()

(optional)

    @callback migration_module() :: module() | nil

# module_key()

    @callback module_key() :: String.t()

# module_name()

    @callback module_name() :: String.t()

# permission_metadata()

(optional)

    @callback permission_metadata() :: permission_meta() | nil

# required_modules()

(optional)

    @callback required_modules() :: [String.t()]

# route_module()

(optional)

    @callback route_module() :: module() | nil

# settings_tabs()

(optional)

    @callback settings_tabs() :: [PhoenixKit.Dashboard.Tab.t()]

# user_dashboard_tabs()

(optional)

    @callback user_dashboard_tabs() :: [PhoenixKit.Dashboard.Tab.t()]

# version()

(optional)

    @callback version() :: String.t()