Developer Guide
Plugin Development
Building modular extensions, custom routes, admin control panels, and lifecycle hooks.
Plugin Development
Encrypt CMS provides a decoupled runtime architecture that allows developers to extend the CMS without touching core files.
1. Directory Structure
Each plugin lives inside its own folder under plugins/{slug}/:
plugins/
└── custom-analytics/
├── plugin.json # Mandatory manifest
├── index.php # Plugin bootstrap entry point
├── README.md # Documentation
├── src/
│ ├── Controllers/
│ │ └── SettingsController.php
│ └── Services/
└── views/
└── admin-settings.php
2. Plugin Manifest (plugin.json)
{
"name": "Custom Analytics",
"slug": "custom-analytics",
"version": "1.0.0",
"author": "Your Name / Organization",
"description": "Lightweight privacy-preserving visitor analytics for Encrypt CMS.",
"settings_url": "/admin/plugins/custom-analytics",
"entry_point": "index.php"
}
3. The Entry Point (index.php)
When an active plugin is booted, Encrypt CMS loads index.php in an isolated scope, passing the $router instance:
<?php
declare(strict_types=1);
use App\Core\Hook;
use App\Core\Router;
// 1. Register plugin PSR-4 autoloader
spl_autoload_register(static function (string $class): void {
$prefix = 'CustomAnalytics\\';
$baseDir = __DIR__ . '/src/';
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
$file = $baseDir . str_replace('\\', '/', substr($class, $len)) . '.php';
if (file_exists($file)) {
require_once $file;
}
});
// 2. Register a custom administrative route
$router->get('/admin/plugins/custom-analytics', function () {
// Render custom administration view
require __DIR__ . '/views/admin-settings.php';
});
// 3. Subscribe to a content lifecycle hook
Hook::addAction('post.published', function (array $context): void {
$postId = $context['id'] ?? 0;
// Execute custom logic on publication
});