Awn Awn
Back to Awn
Documentation menu — Platform API
Reference / Platform API
Version
1.0
Last verified
2026-08-09

Platform API reference

Exact extension-facing signatures:

interface SitePlugin {
    public function key(): PluginKey;
    public function settingsRules(): array;
    public function normalizeSettings(array $settings): array;
    public function render(PluginSlot $slot, PluginRenderContext $context, array $settings): ?View;
}
interface ContributesDashboard { public function dashboards(): array; }
interface ContributesDashboardWidgets {
    public function dashboardWidgets(Organization $organization): array;
}
interface ContributesSuperAdminPages { public function superAdminPages(): array; }
interface ContributesSuperAdminWidgets { public function superAdminWidgets(): array; }
interface ContributesPages {
    public function pages(): array;
    public function renderPage(PluginPage $page, PluginRenderContext $context, array $settings, array $parameters = []): PluginPageResponse;
}
interface SeedsPluginData { public function seeders(): array; }

Value constructors:

new PluginRenderContext(Organization $organization, bool $isPreview, ?string $path = null);
new PluginDashboard(string $id, string $title, string $description, string $routeName, DashboardIcon $icon = DashboardIcon::Grid, int $order = 100, bool $requiresEnabled = true);
new PluginDashboardWidget(string $id, View $view, int $order = 100);
new PluginSuperAdminPage(string $id, string $title, string $description, string $routeName, DashboardIcon $icon = DashboardIcon::Grid, int $order = 100);
new PluginSuperAdminWidget(string $id, View $view, int $order = 100);
new PluginPage(string $id, string $slug, string $title, bool $showInNavigation = true, PluginPageLayout $layout = PluginPageLayout::Contained, int $order = 100);
new PluginPageResponse(string $title, View $view);
new ResolvedPluginPage(PluginKey $plugin, PluginPage $page, string $title, HtmlString $content);

DashboardIcon allowlists inbox, calendar, grid, chart, heart, credit-card, users, check-circle, and folder. Add icons to the enum and shared renderer; never inject arbitrary SVG from plugin settings.

Core methods:

PluginRegistry::get(PluginKey|string $plugin): PluginManifest;
PluginRegistry::all(): Collection;
PluginRegistry::driver(PluginKey $key): SitePlugin;
ThemeRegistry::get(ThemeKey|string $theme): ThemeManifest;
ThemeRegistry::all(): Collection;
ThemeRegistry::default(): ThemeManifest;
PluginResolver::enabledFor(Organization $organization): array;
PluginResolver::enabled(Organization $organization, PluginKey $key): bool;
PluginResolver::forget(Organization $organization): void;
PluginResolver::forgetForPlugin(Plugin $plugin): void;
PluginResolver::forgetByOrganizationId(string $organizationId): void;
PluginRenderer::render(PluginSlot $slot, PluginRenderContext $context): HtmlString;
PluginPageResolver::navigationFor(Organization $organization): array;
PluginPageResolver::resolve(Organization $organization, string $path, bool $isPreview): ?ResolvedPluginPage;
PluginDashboardResolver::forOrganization(Organization $organization): array;
PluginDashboardResolver::groupsForOrganization(Organization $organization): array;
PluginDashboardWidgetResolver::forOrganization(Organization $organization): array;
PluginSuperAdminPageResolver::forPlatform(): array;
PluginSuperAdminPageResolver::groupsForPlatform(): array;
PluginSuperAdminWidgetResolver::forPlatform(): array;
ThemeResolver::resolve(Organization $organization): ResolvedTheme;
ThemeResolver::forget(Organization $organization): void;
PluginManager::synchronizeCatalog(): Collection;
PluginManager::stateFor(Organization $organization, PluginKey $key): PluginEffectiveState;
PluginManager::configure(Organization $organization, PluginKey $key, bool $enabled, array $settings): OrganizationPlugin;
PluginLifecycleManager::install(PluginKey $key): void;
PluginLifecycleManager::uninstall(PluginKey $key, bool $purge): void;
ThemeManager::synchronizeCatalog(): Collection;
ThemeManager::ensureDefaultAssignment(Organization $organization): OrganizationTheme;
ThemeManager::activate(Organization $organization, ThemeKey $key, array $settings): OrganizationTheme;
PluginCompatibilityService::forOrganization(Organization $organization, PluginManifest $plugin): PluginCompatibilityResult;
PluginCompatibilityService::forTheme(PluginManifest $plugin, ThemeManifest $theme): PluginCompatibilityResult;
PluginCompatibilityResult::allowsActivation(): bool;
PluginCompatibilityResult::isEffective(bool $enabled, bool $available = true): bool;
PluginCompatibilityResult::message(): string;
PluginDefinitionValidator::validateRegistry(): void;
PluginDefinitionValidator::assertOrganizationCanEnable(Organization $organization, PluginKey $key): void;
SiteUrlGenerator::for(Organization $organization, ?string $path = null, bool $preview = false): string;

PluginDashboardResolver::groupsForOrganization() returns list<array{key: string, title: string, icon: DashboardIcon, items: list<PluginDashboard>}>. The title is the manifest name and the icon is taken from the group's first ordered item. PluginDashboardWidgetResolver::forOrganization() returns a globally order-sorted list<PluginDashboardWidget>.

PluginSuperAdminPageResolver::groupsForPlatform() has the same group shape with list<PluginSuperAdminPage> items. It and PluginSuperAdminWidgetResolver filter by global installed/active state rather than organization assignment or theme compatibility.

PluginEffectiveState is the single organization-facing state contract. Its booleans are installed, globallyActive, and organizationEnabled, plus PluginCompatibilityResult $compatibility. available() requires installed and globally active; canEnable() also requires compatible; effective() requires all four conditions. Charity catalog and settings screens consume this value instead of reconstructing state independently.

Manifest and settings helpers:

PluginManifest::fromFile(PluginKey $key): self;
PluginManifest::defaults(): array;
PluginManifest::slotPriority(PluginSlot $slot): int;
ThemeManifest::fromFile(ThemeKey $key, string $path): self;
ThemeManifest::defaults(): array;
ThemeManifest::path(): string;
ThemeSettings::from(array $settings, ThemeManifest $manifest): self;
ThemeSettings::toArray(): array;
ThemeSettings::get(string $key, mixed $default = null): mixed;
ThemeSettings::formatNumber(int|float|string $value): string;
ThemeSettings::radiusCss(): string;
ThemeSettings::fontCss(): string;
PluginPage::isDynamic(): bool;
PluginPage::match(string $path): ?array;