# Plugin Development ## Plugin structure ``` plugins/MyPlugin/ ├── MyPlugin.php # Main plugin class (name = folder name) ├── plugin.json # Plugin metadata ├── config.json # Optional configuration └── assets/ # Optional CSS/JS ├── css/ └── scss/ ``` ## plugin.json ```json { "name": "My Plugin", "version": "1.0.0", "author": "Your Name", "description": "Description", "type": "content", "essential": false, "hasConfig": false } ``` ### Fields | Field | Value | Description | |-------|-------|-------------| | `name` | string | Display name in admin | | `version` | string | Version number | | `author` | string | Author | | `description` | string | Short description | | `type` | `"system"` or `"content"` | System (blue badge) or content (green badge) | | `essential` | boolean | Essential plugins cannot be edited/deleted | | `hasConfig` | boolean | Shows a Config button in admin | ## Plugin class example ```php api = $api; } public function getConfig(): array { return [ 'title' => 'My Plugin', 'type' => 'content', 'viewable' => true, ]; } public function getSidebarContent(): string { $title = $this->api ? $this->api->getCurrentPageTitle() : ''; return '
Current page: ' . htmlspecialchars($title) . '
'; } } ``` The plugin class is automatically loaded by `PluginManager` when the plugin is listed in `enabled_plugins` in `config.json`. ## Using the API The API is injected via `setAPI()`, not via a static method. In the front-end context this is a `CMSAPI` instance, in the admin context an `AdminPluginAPI` instance. Both implement `PluginAPIInterface`. ```php // Front-end API (CMSAPI) $this->api->getCurrentPageTitle(); $this->api->getMenu(); $this->api->getConfig('site_title'); $this->api->getCurrentLanguage(); $this->api->isHomepage(); $this->api->createUrl('about-us'); // Admin API (AdminPluginAPI) $this->api->getConfig('analytics.enabled'); $this->api->getContentDir(); $this->api->getEnabledPlugins(); ``` ## Hooks Plugins can implement the following methods for automatic hook registration: **Actions** (no return value): - `onPageLoad` - On page load - `onBeforeRender` - Before rendering - `onAfterRender` - After rendering - `onSearch` - On search - `onMenuBuild` - On menu build **Filters** (return modified value): - `onContentFilter` - Filter content - `onTitleFilter` - Filter title - `onMenuFilter` - Filter menu ## Admin integration Plugins can add custom admin pages via `getAdminMenu()` and `handleAdminRoute()`: ```php public function getAdminMenu(): array { return [ [ 'plugin' => 'MyPlugin', 'route' => 'my-plugin', 'label' => 'My Plugin', 'icon' => 'bi-puzzle', 'section' => 'general', // or 'system' ], ]; } public function handleAdminRoute(string $action): ?string { return '