sam-leighton/botble-rule-plugin icon
public
Published on 8/18/2025
Rule Botble CMS Plugin

Rules

Rules for Working with Botble CMS Plugins

Project Overview

Botble CMS plugins follow a modular architecture that allows for easy extension of the core functionality. Each plugin is a self-contained module with its own controllers, models, views, assets, and configuration files.

All plugins must include a plugin.json file for metadata and are manually registered with Composer autoloader.

Core Concepts

1. Plugin Lifecycle

  • Plugin.php handles the lifecycle:
    • activate(): Run logic when plugin is activated (e.g., default settings)
    • deactivate(): Run logic when plugin is deactivated
    • remove(): Clean up database tables, settings, and other data

2. plugin.json

Each plugin requires a plugin.json file with the following fields:

  • name: Display name of the plugin
  • namespace: PHP namespace of the plugin (must end with double backslash)
  • provider: Fully qualified ServiceProvider class
  • author: Plugin author
  • url: Website for the plugin or author
  • version: Plugin version
  • description: Brief description
  • minimum_core_version: Minimum Botble CMS version required

Example:

{
    "name": "Foo",
    "namespace": "Botble\\Foo\\",
    "provider": "Botble\\Foo\\Providers\\FooServiceProvider",
    "author": "Your Name",
    "url": "https://yourwebsite.com",
    "version": "1.0",
    "description": "A simple foo plugin for Botble CMS",
    "minimum_core_version": "7.3.0"
}

3. Directory Structure

platform/plugins/foo/
├── config/
│   └── permissions.php
├── database/
│   ├── migrations/
│   └── seeders/
├── helpers/
├── resources/
│   ├── assets/
│   ├── lang/
│   └── views/
├── routes/
│   └── web.php
├── src/
│   ├── Forms/
│   ├── Http/
│   │   ├── Controllers/
│   │   └── Requests/
│   ├── Models/
│   ├── Providers/
│   │   └── FooServiceProvider.php
│   ├── Repositories/
│   └── Plugin.php
└── plugin.json

4. Service Provider

  • Registers routes, views, translations, migrations, and assets
  • Uses register() to bind implementations to the service container
  • Uses boot() to load and publish configurations, views, translations, migrations, and register menu items
  • Can use LoadAndPublishDataTrait for helper methods like loadHelpers() and loadRoutes()

5. Configuration: permissions.php

Defines hierarchical permissions for the plugin:

return [
    [
        'name' => 'Foo',
        'flag' => 'foo.index',
    ],
    [
        'name' => 'Create',
        'flag' => 'foo.create',
        'parent_flag' => 'foo.index',
    ],
    [
        'name' => 'Edit',
        'flag' => 'foo.edit',
        'parent_flag' => 'foo.index',
    ],
    [
        'name' => 'Delete',
        'flag' => 'foo.destroy',
        'parent_flag' => 'foo.index',
    ],
];

6. Naming Conventions

  • Plugins & Classes: PascalCase (FooServiceProvider)
  • Routes: kebab-case (foo.items.create)
  • Variables: snake_case ($item_count)
  • Constants: SCREAMING_SNAKE_CASE (FOO_MODULE_SCREEN_NAME)
  • Translation Keys: dot notation and lowercase (plugins/foo::items.create)
  • Methods: camelCase (getItems())

Best Practices

  • Keep the plugin self-contained
  • Always provide default settings on activation
  • Clean up database and settings on removal
  • Follow the standard directory structure
  • Load helpers, routes, views, translations, and migrations through the service provider