Home / Docs / plugins
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
});