New features: - ContentBackup class with ZIP backup/restore and git versioning - Admin backup & restore page (content-backup.twig) with git init/commit/log/restore - Plugin type system: system (blue) vs content (green) with visual badges - PluginAPIInterface + AdminPluginAPI for plugin architecture - Essential plugin flag (cannot edit/deactivate/delete) Improvements: - Consolidated enabled_plugins config (removed plugins.enabled) - Removed Analytics/Logging toggles from admin config page - Fixed Dashboard plugin Twig comments rendered as text - Updated 20 guide files (NL+EN): configuratie, plugins, plugin-development, core-classes, theme-json, layouts, scss-styling, admin-beheerder, nieuw-thema, architectuur - Improved accessibility test script (grep -E, min/max checks) Cleanup: - Removed unused classes: ARIAComponents, AccessibilityManager, ContentSecurityPolicy, etc. - Removed vendor packages: mustache/mustache, php-mqtt/client - Removed old templates: logs.twig, statistics.twig (now plugins) - Moved language files to language/ directory Tests: - Pentest: 30/30 passed, 0 vulnerabilities - WCAG 2.1 AA: 25/25 passed, 100% compliance
3.4 KiB
3.4 KiB
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
{
"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
class MyPlugin
{
private ?PluginAPIInterface $api = null;
public function setAPI(PluginAPIInterface $api): void
{
$this->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 '<p>Current page: ' . htmlspecialchars($title) . '</p>';
}
}
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.
// 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 loadonBeforeRender- Before renderingonAfterRender- After renderingonSearch- On searchonMenuBuild- On menu build
Filters (return modified value):
onContentFilter- Filter contentonTitleFilter- Filter titleonMenuFilter- Filter menu
Admin integration
Plugins can add custom admin pages via getAdminMenu() and handleAdminRoute():
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 '<h2>My Plugin admin page</h2>';
}
Only plugins listed in enabled_plugins are shown in the admin sidebar.
Adding CSS
Plugins can provide a CSS URL via getCssUrl():
public function getCssUrl(): string
{
return '/plugins/MyPlugin/assets/css/style.css';
}