Plugin development

Plugin layout, activation, and plugin.json.

Layout

plugins/
  └── your-plugin/
      ├── plugin.json      # Manifest (required)
      └── index.php        # Bootstrap (or path from Plugin model)

plugin.json

Contains at minimum:

  • name, slug, version
  • description, author, author_url (recommended)
  • requires.cms_version — semver constraint when applicable

Example (simplified):

{
  "name": "Hello World",
  "slug": "hello-world",
  "version": "1.0.0",
  "description": "Example plugin.",
  "author": "Your Name",
  "requires": { "cms_version": "^1.0.0" }
}

Bootstrap file

The active plugin’s entry file is loaded during application boot (see PluginServiceProvider). Use it to:

  • Call add_action / add_filter
  • Register bindings if needed

Study plugins/hello-world/ and plugins/reading-time/ in the repository.

Custom Routing (routes.php)

In addition to index.php, you can create a routes.php file in your plugin folder. Any route registered here will automatically be prefixed with /_plugin/your-plugin-slug and given the name prefix plugin.your-plugin-slug. to prevent conflicts with the core CMS routes.

Plugin Settings (Settings UI)

Plugins can effortlessly render a Settings form in the Admin UI. Simply define a settings_schema in your plugin.json.

  "settings_schema": {
    "fields": [
      { "key": "api_key", "label": "API Key", "type": "text" },
      { "key": "enable_feature", "label": "Enable Feature", "type": "boolean", "default": true }
    ]
  }

These values are saved as JSON in the database on the plugins table.

Uninstall Hook (uninstall.php)

When a user deletes a plugin from the Admin UI, the uninstall.php file (if it exists) will be executed right before the folder is permanently deleted. This is ideal for cleaning up database leftovers or temporary files. The system will set NEBULA_PLUGIN_UNINSTALL=1 in the environment during its execution.

Dependencies and Requirement Validation

You can strictly enforce minimum constraints, preventing users from activating the plugin if they aren't met, using the requires block in plugin.json. This also supports enforcing dependencies on other plugins (requires.plugins). NebulaCMS guarantees that dependency plugins are loaded first by sorting them topologically.

  "requires": {
    "cms_version": "^1.0.0",
    "php": "^8.3",
    "plugins": ["another-plugin-slug"]
  }

Admin UI

Plugins appear under Admin → Plugins (scan, activate, deactivate, upload, settings, delete). Permissions may apply depending on configuration.

See also