What is a plugin

What is a plugin

A plugin is a self-contained package that extends Celena without changing its core. It can:

  • add pages to the admin and/or the front;
  • register new template-engine tags and async blocks;
  • subscribe to core hooks (news.published, user.registered, etc.) and emit its own;
  • have its own migrations, models and services;
  • be distributed via the marketplace or manually (zip).

A key principle: the core is self-sufficient. Everything works without a plugin; a plugin only extends through hooks and does not modify the core. Plugins can be enabled and disabled in the Plugins section of the control panel.

Structure

plugins/<slug>/
├── manifest.json     metadata (required)
├── plugin.php        entry point (required)
├── README.md         recommended
├── migrations/       DB migrations (optional)
├── src/              PHP classes (PSR-4 Celena\Plugin\<Slug>\)
│   ├── Controllers/
│   ├── Admin/
│   ├── Repositories/
│   └── Support/
├── templates/        plugin .tpl (admin and front)
├── languages/        ru.json, en.json, etc.
├── assets/           CSS/JS → copied to public/assets/plugins/<slug>/
└── docs/             plugin Markdown documentation

manifest.json

{
  "slug": "shop",
  "name": "Online store",
  "version": "1.0.0",
  "author": "Celena",
  "description": "Catalog, cart, orders, payments.",
  "requires": { "php": ">=8.3", "celena": ">=1.0", "plugins": [] },
  "permissions": ["news.read", "options.write"],
  "migrations": "migrations/"
}

The slug field is required and must match ^[a-z0-9][a-z0-9_\-]*$. The folder name = slug.

How the core finds and loads plugins

  1. PluginManager::discover() scans plugins/* and reads each manifest.json.
  2. The list of active plugins is stored in the active_plugins option (a JSON array of slugs in the cl_celena_options table).
  3. For active plugins PluginManager::load():
    • registers the Celena\Plugin\<Slug>\ namespace → plugins/<slug>/src/;
    • includes plugin.php (where routes, hooks and tags are registered);
    • syncs assets/ to public/assets/plugins/<slug>/.

Enabling/disabling a plugin = adding/removing its slug in active_plugins (via the admin). Migrations run on first enable.

Reference plugins

The bundle ships with working plugins — study them as templates:

  • plugins/leads/ — a form builder and lead intake (forms, honeypot, export, injecting the form into the landing). A good minimal example.
  • plugins/analytics/ — first-party analytics (tracker, events, goals, dashboard).
  • plugins/shop/ — a large e-commerce plugin (catalog, cart, orders) — an example of a big plugin.

Next — building a plugin step by step.