From 3b2091ee76d4161e3f16ac5ec2699a34fe558139 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Thu, 30 Oct 2025 15:41:24 +0100 Subject: [PATCH 01/15] add plugin docs --- docs/panel/advanced/plugins.mdx | 190 ++++++++++++++++++++++++++++++++ docusaurus.config.ts | 3 +- sidebars.ts | 1 + 3 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 docs/panel/advanced/plugins.mdx diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx new file mode 100644 index 00000000..10e8f2fe --- /dev/null +++ b/docs/panel/advanced/plugins.mdx @@ -0,0 +1,190 @@ +import Admonition from '@theme/Admonition'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Plugins + +Plugins allow you to add new functionality to the panel without modifying any panel core files. + + + The plugin system is still in development and features might be missing! + + +## Install a Plugin + + + + Use the Import Button on the plugin list to upload & install a plugin. + + + Move the plugin folder to `/var/www/pelican/plugins`. Then run `php artisan p:plugin:install` and select the new plugin. + + + +## Create a Plugin + + + You **need** at least basic [PHP](https://php.net), [Laravel](https://laravel.com) and [Filament](https://filamentphp.com) knowledge to create plugins! + + +Use `php artisan p:plugin:make` to create the basic files and folders for your new plugin. This will create the `plugin.json`, the main plugin file, a config file and a service provider. + +### Plugin Structure + +The two most important files of your plugin are the `plugin.json` (which contains general information like name, version etc.) and the main plugin file. (where you can load Filament resources, pages etc.) +While the `plugin.json` is in the root of your plugin folder, the main plugin file is in `src`. + +In general the plugin folder tries to mimic the structure of a normal Laravel/ FilamentPHP project. For example, translations go into `lang` and migrations are in `database/migrations`. +Everything is auto discovered and service providers, artisan commands, migrations etc. are automatically registered. + +The only exception to a normal Laravel project is the `app` folder, it is called `src` instead. Besides that is still follows the same sub-structure, e.g. models go in `src/Models` and service providers are in `src/Providers`. + + + The plugin id and the plugin folder name need to match! + + +### Filament Resources + +To simply register Filament resources, pages or widgets you can add the following snippet to the `register` function in your main plugin file: + +```php {3-5} +$id = str($panel->getId())->title(); + +$panel->discoverPages(plugin_path($this->getId(), "src/Filament/$id/Pages"), "\\Filament\\$id\\Pages"); +$panel->discoverResources(plugin_path($this->getId(), "src/Filament/$id/Resources"), "\\Filament\\$id\\Resources"); +$panel->discoverWidgets(plugin_path($this->getId(), "src/Filament/$id/Widgets"), "\\Filament\\$id\\Widgets"); +``` + +Make sure to replace `` with your actual namespace. + +### Translations + +Normally, translations will be registered under the namespace of your plugin. +This means you need to prefix translation keys with your plugin id when using `trans()`, e.g. `trans('myplugin::strings.test')` would look for `test` inside `plugins/myplugin/lang/strings.php`. + +If your plugin adds new default languages to the panel you need to set the plugin category to `language`. This way translations will be registered without any namespace. + +## Views + +View are automatically registered under the namespace of your plugin. +This means you need to prefix view-strings with your plugin id, e.g. `myplugin::my-view` would look for `my-view.blade.php` inside `plugins/myplugin/resources/views`. + +### Plugin Settings + +Your main plugin class can implement the `HasPluginSettings` interface to conveniently add a settings page to your plugin. +The settings page can be accessed on the plugin list on the panel. Your plugin needs to provide the form and how the data should be saved. + +If you want to save the settings in the `.env` file you can use the `EnvironmentWriterTrait`. Example: + +```php +use EnvironmentWriterTrait; + +public function getSettingsForm(): array +{ + return [ + TextInput::make('test_input') + ->required() + ->default(fn () => config('myplugin.test_input')), + Toggle::make('test_toggle') + ->inline(false) + ->default(fn () => config('myplugin.test_toggle')), + ]; +} + +public function saveSettings(array $data): void +{ + $this->writeToEnvironment([ + 'MYPLUGIN_TEST_INPUT' => $data['test_input'], + 'MYPLUGIN_TEST_TOGGLE' => $data['test_toggle'], + ]); + + Notification::make() + ->title('Settings saved') + ->success() + ->send(); +} +``` + + + When adding new environment variables make sure to prefix them with your plugin id, e.g. `MYPLUGIN_TEST_INPUT` and not just `TEST_INPUT`. + + +### Modify existing resources + +Most of the default panel resources and pages have static methods to register custom classes or to change existing ones. You can call these static methods inside the `register` function of a service provider. + +Examples: + +```php title="MyPluginProvider.php" +public function register(): void +{ + // Add new relation manager to UserResource + UserResource::registerCustomRelations(MyCustomRelationManager::class); + + // Add new widget to Console page + Console::registerCustomWidgets(ConsoleWidgetPosition::AboveConsole, [MyCustomWidget::class]); + + // Add new header action to Server list page + ListServers::registerCustomHeaderActions(HeaderActionPosition::Before, MyCustomAction::make()); +} +``` + +For more information you can check the ["CanModify" and "CanCustomize" traits in `./app/Traits/Filament`](https://github.com/Boy132/pelican-panel/tree/main/app/Traits/Filament). + +### Add new role permissions + +To add new (admin) role permissions you can use `Role::registerCustomPermissions` and `Role::registerCustomDefaultPermissions`. You can call these static methods inside the `register` function of a service provider. + +Examples: + +```php title="MyPluginProvider.php" +public function register(): void +{ + // Register default permissions: viewList, view, create, update, delete + Role::registerCustomDefaultPermissions('myModel'); + + // Register custom permissions + Role::registerCustomPermissions([ + 'myModel' => [ + 'customPerm1', + 'customPerm2' + ] + ]); + + // You can also add new permissions to existing models + Role::registerCustomPermissions([ + 'server' => [ + 'custom', + ] + ]); +} +``` + + + This will only work for admin role permisions, not subuser permissions! + + +### Additional composer dependencies + +If you need additional composer packages as dependency for your plugin you can add the package name to the `composer_packages` array in your `plugin.json`: + +```json +"composer_packages": { + "package/one": "^1.0", + "package/two": "^1.0" +} +``` + +## Publish a Plugin + +To publish a plugin you only need to do two things: + +1. Open your `plugin.json` and remove the `meta` part. +2. Zip up your whole plugin folder. + +And that's it! Now you can take the zip file and share it with the world! + + + You can license your plugin code under whatever license you want. You do not have to use the same license as the panel! + You also don't have to open source your plugin code. But if you do want to open source it we recommend [MIT](https://choosealicense.com/licenses/mit) or [GPL v3](https://choosealicense.com/licenses/gpl-3.0) as license. + \ No newline at end of file diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 7126aedd..41cae8fa 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -108,6 +108,7 @@ const config: Config = { "ini", "sql", "yaml", + "php", ], }, } satisfies Preset.ThemeConfig, @@ -136,7 +137,7 @@ const config: Config = { ], tailwindPlugin, ], - future:{ + future: { experimental_faster: true, v4: true } diff --git a/sidebars.ts b/sidebars.ts index e1d56ee8..6d8c5777 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -31,6 +31,7 @@ const sidebars: SidebarsConfig = { 'panel/advanced/mysql', 'panel/advanced/artisan', 'panel/advanced/docker', + 'panel/advanced/plugins', ] } ], From f602edeefbcf18416930465a7fbcbd95f9845c04 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Fri, 31 Oct 2025 09:53:13 +0100 Subject: [PATCH 02/15] add info about discord-help and marketplace --- docs/panel/advanced/plugins.mdx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index 10e8f2fe..c2519d45 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -29,6 +29,10 @@ Plugins allow you to add new functionality to the panel without modifying any pa Use `php artisan p:plugin:make` to create the basic files and folders for your new plugin. This will create the `plugin.json`, the main plugin file, a config file and a service provider. + + Visit our [Discord](https://discord.gg/pelican-panel) if you need any help when creating plugins! + + ### Plugin Structure The two most important files of your plugin are the `plugin.json` (which contains general information like name, version etc.) and the main plugin file. (where you can load Filament resources, pages etc.) @@ -184,6 +188,11 @@ To publish a plugin you only need to do two things: And that's it! Now you can take the zip file and share it with the world! + + We are currently working on adding a plugin marketplace to the [Hub](https://hub.pelican.dev). + Until then you can publish your plugins on our [plugins repo](https://github.com/pelican-dev/plugins). You can also share them in the `#plugins` channel in our [Discord](https://discord.gg/pelican-panel). + + You can license your plugin code under whatever license you want. You do not have to use the same license as the panel! You also don't have to open source your plugin code. But if you do want to open source it we recommend [MIT](https://choosealicense.com/licenses/mit) or [GPL v3](https://choosealicense.com/licenses/gpl-3.0) as license. From e56a43412a10face8015047ce81ae38b870484ff Mon Sep 17 00:00:00 2001 From: Boy132 Date: Wed, 5 Nov 2025 12:45:39 +0100 Subject: [PATCH 03/15] add info about beta --- docs/panel/advanced/plugins.mdx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index c2519d45..b5a51cdd 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -181,6 +181,11 @@ If you need additional composer packages as dependency for your plugin you can a ## Publish a Plugin + + While Pelican is still in beta, please do **not** sell plugins. Also, if possible, please make them open source. + During the beta we still add new features and change existing ones. So keeping your plugins open helps us to improve the plugin system! + + To publish a plugin you only need to do two things: 1. Open your `plugin.json` and remove the `meta` part. From 8ad7165b63d98082080f3139ab2bbcda6ccc4f89 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Wed, 5 Nov 2025 12:54:59 +0100 Subject: [PATCH 04/15] add info about filament panels --- docs/panel/advanced/plugins.mdx | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index b5a51cdd..8b5b3675 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -61,6 +61,39 @@ $panel->discoverWidgets(plugin_path($this->getId(), "src/Filament/$id/Widgets"), Make sure to replace `` with your actual namespace. +### Filament Panels + +By default there are three Filament panels: + +1. `admin` (Admin Area) +2. `app` (Server list) +3. `server` (Client Area) + +The `server` panel uses the `Server` model as [tenant](https://filamentphp.com/docs/4.x/users/tenancy). + +The `app` panel is solely used for the server list and has no navigation. +If you want to expand the `app` panel, you can re-enable the navigation by adding the following snippet to the `register` function in your main plugin file: + +```php +if ($panel->getId() === 'app') { + // Optional: "Embed" the server list. This will add a Servers navigation item for the server list. + // ServerResource::embedServerList(); + + // Re-enable navigation + $panel->navigation(true); + + // By default the topbar is always used. With proper navigation we want to conditionally enable it based on the users customization + $panel->topbar(function () { + $navigationType = user()?->getCustomization(CustomizationKey::TopNavigation); + + return $navigationType === 'topbar' || $navigationType === 'mixed' || $navigationType === true; + }); + + // Rebuild component cache + $panel->clearCachedComponents(); +} +``` + ### Translations Normally, translations will be registered under the namespace of your plugin. From 0f291a5a06491d7a9f7522171ed618ba968544a0 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Thu, 6 Nov 2025 10:21:10 +0100 Subject: [PATCH 05/15] small wording changes --- docs/panel/advanced/plugins.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index 8b5b3675..a4708074 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -38,13 +38,13 @@ Use `php artisan p:plugin:make` to create the basic files and folders for your n The two most important files of your plugin are the `plugin.json` (which contains general information like name, version etc.) and the main plugin file. (where you can load Filament resources, pages etc.) While the `plugin.json` is in the root of your plugin folder, the main plugin file is in `src`. -In general the plugin folder tries to mimic the structure of a normal Laravel/ FilamentPHP project. For example, translations go into `lang` and migrations are in `database/migrations`. +In general, the plugin folder tries to mimic the structure of a normal Laravel/ FilamentPHP project. For example, translations go into `lang` and migrations are in `database/migrations`. Everything is auto discovered and service providers, artisan commands, migrations etc. are automatically registered. The only exception to a normal Laravel project is the `app` folder, it is called `src` instead. Besides that is still follows the same sub-structure, e.g. models go in `src/Models` and service providers are in `src/Providers`. - The plugin id and the plugin folder name need to match! + The plugin id and the plugin root folder name need to match! ### Filament Resources @@ -67,9 +67,9 @@ By default there are three Filament panels: 1. `admin` (Admin Area) 2. `app` (Server list) -3. `server` (Client Area) +3. `server` (Client Area, with `Server` model as [tenant](https://filamentphp.com/docs/4.x/users/tenancy)) -The `server` panel uses the `Server` model as [tenant](https://filamentphp.com/docs/4.x/users/tenancy). +#### App panel The `app` panel is solely used for the server list and has no navigation. If you want to expand the `app` panel, you can re-enable the navigation by adding the following snippet to the `register` function in your main plugin file: @@ -104,7 +104,7 @@ If your plugin adds new default languages to the panel you need to set the plugi ## Views View are automatically registered under the namespace of your plugin. -This means you need to prefix view-strings with your plugin id, e.g. `myplugin::my-view` would look for `my-view.blade.php` inside `plugins/myplugin/resources/views`. +This means you need to prefix view-strings with your plugin id, e.g. `myplugin::my-view` would look for `plugins/myplugin/resources/views/my-view.blade.php`. ### Plugin Settings @@ -166,7 +166,7 @@ public function register(): void } ``` -For more information you can check the ["CanModify" and "CanCustomize" traits in `./app/Traits/Filament`](https://github.com/Boy132/pelican-panel/tree/main/app/Traits/Filament). +For more information you can check the ["CanModify" and "CanCustomize" traits in `./app/Traits/Filament`](https://github.com/pelican-dev/panel/tree/main/app/Traits/Filament). ### Add new role permissions From ae7f2c671d629a13a91293cdaa1b3a512d90266e Mon Sep 17 00:00:00 2001 From: Boy132 Date: Thu, 6 Nov 2025 10:24:02 +0100 Subject: [PATCH 06/15] add info about update_url --- docs/panel/advanced/plugins.mdx | 47 ++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index a4708074..96dd7224 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -101,7 +101,7 @@ This means you need to prefix translation keys with your plugin id when using `t If your plugin adds new default languages to the panel you need to set the plugin category to `language`. This way translations will be registered without any namespace. -## Views +### Views View are automatically registered under the namespace of your plugin. This means you need to prefix view-strings with your plugin id, e.g. `myplugin::my-view` would look for `plugins/myplugin/resources/views/my-view.blade.php`. @@ -212,6 +212,51 @@ If you need additional composer packages as dependency for your plugin you can a } ``` +### Update URL + +In your `plugin.json` you can specify an `update_url` that is fetched when checking for plugin updates. It needs to point directly to a json file with the following format: + +```json title="update.json" +{ + "panel_version_1": { + "version": "1.0.0", + "download_url": "..." + }, + "panel_version_2": { + "version": "1.1.0", + "download_url": "... + } +} +``` + +If you don't have panel version specific plugin versions you can also use `*` as panel version wildcard: + +```json title="update.json" +{ + "*": { + "version": "1.1.0", + "download_url": "... + } +} +``` + +You can also mix the wildcard with real panel versions. This way the wildcard will be used as fallback when the users panel version isn't specified in the update json. + +Example: + +```json title="update.json" +{ + "panel_version_1": { + "version": "1.0.0", + "download_url": "..." + }, + "*": { + "version": "1.1.0", + "download_url": "... + } +} +``` + ## Publish a Plugin From 6598993f2d5fb5ec60804f224dc0470dfbf34557 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Thu, 6 Nov 2025 10:28:30 +0100 Subject: [PATCH 07/15] add info about plugins repo --- docs/panel/advanced/plugins.mdx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index 96dd7224..f4b2f614 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -21,6 +21,11 @@ Plugins allow you to add new functionality to the panel without modifying any pa + + Check out our [Plugins repo](https://github.com/pelican-dev/plugins)! It contains free and open source plugins created by the Pelican team and the community. + We are also working on adding a plugin marketplace to the [Hub](https://hub.pelican.dev). + + ## Create a Plugin From bbc25ac58f5d8a4c56021bf290939bc28a643f6d Mon Sep 17 00:00:00 2001 From: Boy132 Date: Fri, 7 Nov 2025 10:27:00 +0100 Subject: [PATCH 08/15] add info about plugin.json fields --- docs/panel/advanced/plugins.mdx | 123 ++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 45 deletions(-) diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index f4b2f614..dbc1351d 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -52,6 +52,84 @@ The only exception to a normal Laravel project is the `app` folder, it is called The plugin id and the plugin root folder name need to match! +#### plugin.json + +Most of the fields inside the `plugin.json` are generated when running the [artisan command](#create-a-plugin). + +| Field | Required | Description | +| ----------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| id | Yes | Unique identifier of the plugin. Has to match with the plugin root folder name! | +| name | Yes | Display name of the plugin. | +| author | Yes | Display name of the plugin creator. | +| version | No | Version of the plugin. Ideally, this should follow [semantic versioning](https://semver.org/). When not set it will assume version 1.0.0. | +| description | No | Short description of the plugin. | +| category | Yes | Either `plugin`, `theme` or `language`. | +| update_url | No | URL that will be fetched when checking for updates. See [below](#update-url) for more information. | +| namespace | Yes | The php namespace for the plugin files. | +| class | Yes | The name of the plugin main class. | +| panels | No | Array of [FilamentPHP panel](#filament-panels) ids the plugin should be loaded on. When not set the plugin will be loaded on all panels. | +| panel_version | No | The panel version required for the plugin. See [below](#panel-version) for more information. | +| composer_packages | No | Array of additional composer packages. Key is the package name and value is the version. | + + + You can ignore the `meta` fields. Those are used internally to keep track of the plugin status and load order. + + +#### Update URL + +In your `plugin.json` you can specify an `update_url` that is fetched when checking for plugin updates. +When not set, there will be no update checking for the plugin. + +It needs to point directly to a json file with the following format: + +```json title="update.json" +{ + "panel_version_1": { + "version": "1.0.0", + "download_url": "..." + }, + "panel_version_2": { + "version": "1.1.0", + "download_url": "... + } +} +``` + +If you don't have panel version specific plugin versions you can also use `*` as panel version wildcard: + +```json title="update.json" +{ + "*": { + "version": "1.1.0", + "download_url": "... + } +} +``` + +You can also mix the wildcard with real panel versions. This way the wildcard will be used as fallback when the users panel version isn't specified in the update json. + +Example: + +```json title="update.json" +{ + "panel_version_1": { + "version": "1.0.0", + "download_url": "..." + }, + "*": { + "version": "1.1.0", + "download_url": "... + } +} +``` + +#### Panel version + +In your `plugin.json` you can specify a `panel_version` that is used for compatibility checks. +When not set, the plugin will be loaded regardless of the panel version. + +You can add a `^` in front of the version to make it a minimum constraint instead of a strict one, e.g. `1.2.0` means "_only_ version 1.2.0" while `^1.2.0` means "version 1.2.0 _or higher_". + ### Filament Resources To simply register Filament resources, pages or widgets you can add the following snippet to the `register` function in your main plugin file: @@ -217,51 +295,6 @@ If you need additional composer packages as dependency for your plugin you can a } ``` -### Update URL - -In your `plugin.json` you can specify an `update_url` that is fetched when checking for plugin updates. It needs to point directly to a json file with the following format: - -```json title="update.json" -{ - "panel_version_1": { - "version": "1.0.0", - "download_url": "..." - }, - "panel_version_2": { - "version": "1.1.0", - "download_url": "... - } -} -``` - -If you don't have panel version specific plugin versions you can also use `*` as panel version wildcard: - -```json title="update.json" -{ - "*": { - "version": "1.1.0", - "download_url": "... - } -} -``` - -You can also mix the wildcard with real panel versions. This way the wildcard will be used as fallback when the users panel version isn't specified in the update json. - -Example: - -```json title="update.json" -{ - "panel_version_1": { - "version": "1.0.0", - "download_url": "..." - }, - "*": { - "version": "1.1.0", - "download_url": "... - } -} -``` - ## Publish a Plugin From 86f3929031279b49c4970ee5356cf31921f82040 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 1 Dec 2025 14:35:17 +0100 Subject: [PATCH 09/15] move things around --- docs/panel/advanced/plugins.mdx | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index dbc1351d..c4118b62 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -123,6 +123,19 @@ Example: } ``` +#### Additional composer dependencies + +If you need additional composer packages as dependency for your plugin, you can add the package name to the `composer_packages` array in your `plugin.json`. + +Example: + +```json +"composer_packages": { + "package/one": "^1.0", + "package/two": "^1.0" +} +``` + #### Panel version In your `plugin.json` you can specify a `panel_version` that is used for compatibility checks. @@ -284,17 +297,6 @@ public function register(): void This will only work for admin role permisions, not subuser permissions! -### Additional composer dependencies - -If you need additional composer packages as dependency for your plugin you can add the package name to the `composer_packages` array in your `plugin.json`: - -```json -"composer_packages": { - "package/one": "^1.0", - "package/two": "^1.0" -} -``` - ## Publish a Plugin From 44f3363350345d992f4a15d2fad44727de7a9ab5 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Mon, 1 Dec 2025 14:47:49 +0100 Subject: [PATCH 10/15] change wording and add info about role model icons --- docs/panel/advanced/plugins.mdx | 35 ++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index c4118b62..e6053260 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -32,7 +32,7 @@ Plugins allow you to add new functionality to the panel without modifying any pa You **need** at least basic [PHP](https://php.net), [Laravel](https://laravel.com) and [Filament](https://filamentphp.com) knowledge to create plugins! -Use `php artisan p:plugin:make` to create the basic files and folders for your new plugin. This will create the `plugin.json`, the main plugin file, a config file and a service provider. +Run `php artisan p:plugin:make` to create the basic files and folders for your new plugin. This will create the `plugin.json`, the main plugin file, a config file and a service provider. Visit our [Discord](https://discord.gg/pelican-panel) if you need any help when creating plugins! @@ -56,20 +56,20 @@ The only exception to a normal Laravel project is the `app` folder, it is called Most of the fields inside the `plugin.json` are generated when running the [artisan command](#create-a-plugin). -| Field | Required | Description | -| ----------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -| id | Yes | Unique identifier of the plugin. Has to match with the plugin root folder name! | -| name | Yes | Display name of the plugin. | -| author | Yes | Display name of the plugin creator. | -| version | No | Version of the plugin. Ideally, this should follow [semantic versioning](https://semver.org/). When not set it will assume version 1.0.0. | -| description | No | Short description of the plugin. | -| category | Yes | Either `plugin`, `theme` or `language`. | -| update_url | No | URL that will be fetched when checking for updates. See [below](#update-url) for more information. | -| namespace | Yes | The php namespace for the plugin files. | -| class | Yes | The name of the plugin main class. | -| panels | No | Array of [FilamentPHP panel](#filament-panels) ids the plugin should be loaded on. When not set the plugin will be loaded on all panels. | -| panel_version | No | The panel version required for the plugin. See [below](#panel-version) for more information. | -| composer_packages | No | Array of additional composer packages. Key is the package name and value is the version. | +| Field | Required | Description | +| ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| id | Yes | Unique identifier of the plugin. Has to match with the plugin root folder name! | +| name | Yes | Display name of the plugin. | +| author | Yes | Display name of the plugin creator. | +| version | No | Version of the plugin. Ideally, this should follow [semantic versioning](https://semver.org/). When not set it will assume version 1.0.0. | +| description | No | Short description of the plugin. | +| category | Yes | Either `plugin`, `theme` or `language`. | +| update_url | No | URL that will be fetched when checking for updates. See [below](#update-url) for more information. | +| namespace | Yes | The php namespace for the plugin files. | +| class | Yes | The name of the plugin main class. | +| panels | No | Array of [FilamentPHP panel](#filament-panels) ids the plugin should be loaded on. When not set the plugin will be loaded on all panels. | +| panel_version | No | The panel version required for the plugin. See [below](#panel-version) for more information. | +| composer_packages | No | Array of additional composer packages. Key is the package name and value is the version. See [below](#additional-composer-dependencies) for more information. | You can ignore the `meta` fields. Those are used internally to keep track of the plugin status and load order. @@ -284,6 +284,9 @@ public function register(): void ] ]); + // Optionally, register an icon for a custom model + Role::registerCustomModelIcon('myModel', 'tabler-star'); + // You can also add new permissions to existing models Role::registerCustomPermissions([ 'server' => [ @@ -294,7 +297,7 @@ public function register(): void ``` - This will only work for admin role permisions, not subuser permissions! + This will only work for admin role permisions, not subuser permissions! There is currently no way to register custom subuser permissions. ## Publish a Plugin From 9bd129b922c282c17571c1d747287eea0a17aa65 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Thu, 4 Dec 2025 11:01:10 +0100 Subject: [PATCH 11/15] small spelling and grammar changes --- docs/panel/advanced/plugins.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index e6053260..6e7a7b28 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -43,10 +43,10 @@ Run `php artisan p:plugin:make` to create the basic files and folders for your n The two most important files of your plugin are the `plugin.json` (which contains general information like name, version etc.) and the main plugin file. (where you can load Filament resources, pages etc.) While the `plugin.json` is in the root of your plugin folder, the main plugin file is in `src`. -In general, the plugin folder tries to mimic the structure of a normal Laravel/ FilamentPHP project. For example, translations go into `lang` and migrations are in `database/migrations`. -Everything is auto discovered and service providers, artisan commands, migrations etc. are automatically registered. +In general, the plugin folder tries to mimic the structure of a normal Laravel/FilamentPHP project. For example, translations go into `lang` and migrations are in `database/migrations`. +Everything is auto-discovered and service providers, artisan commands, migrations etc. are automatically registered. -The only exception to a normal Laravel project is the `app` folder, it is called `src` instead. Besides that is still follows the same sub-structure, e.g. models go in `src/Models` and service providers are in `src/Providers`. +The only exception to a normal Laravel project is the `app` folder, it is called `src` instead. Besides that, is still follows the same sub-structure, e.g. models go in `src/Models` and service providers are in `src/Providers`. The plugin id and the plugin root folder name need to match! @@ -95,7 +95,7 @@ It needs to point directly to a json file with the following format: } ``` -If you don't have panel version specific plugin versions you can also use `*` as panel version wildcard: +If you don't have panel-version-specific plugin versions, you can also use `*` as panel version wildcard: ```json title="update.json" { @@ -199,7 +199,7 @@ If your plugin adds new default languages to the panel you need to set the plugi ### Views -View are automatically registered under the namespace of your plugin. +Views are automatically registered under the namespace of your plugin. This means you need to prefix view-strings with your plugin id, e.g. `myplugin::my-view` would look for `plugins/myplugin/resources/views/my-view.blade.php`. ### Plugin Settings @@ -297,7 +297,7 @@ public function register(): void ``` - This will only work for admin role permisions, not subuser permissions! There is currently no way to register custom subuser permissions. + This will only work for admin role permissions, not subuser permissions! There is currently no way to register custom subuser permissions. ## Publish a Plugin From 32a46eefcc58d0e70d71e68cd392865df128d619 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Thu, 4 Dec 2025 11:02:17 +0100 Subject: [PATCH 12/15] fix examples --- docs/panel/advanced/plugins.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index 6e7a7b28..6181f577 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -90,7 +90,7 @@ It needs to point directly to a json file with the following format: }, "panel_version_2": { "version": "1.1.0", - "download_url": "... + "download_url": "..." } } ``` @@ -101,7 +101,7 @@ If you don't have panel-version-specific plugin versions, you can also use `*` a { "*": { "version": "1.1.0", - "download_url": "... + "download_url": "..." } } ``` @@ -118,7 +118,7 @@ Example: }, "*": { "version": "1.1.0", - "download_url": "... + "download_url": "..." } } ``` From 8f0fa8ff8ed6dff48662ec964bd512e1fbdf8a32 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Thu, 11 Dec 2025 14:58:57 +0100 Subject: [PATCH 13/15] add info about custom subuser permissions --- docs/panel/advanced/plugins.mdx | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index 6181f577..1aa1c0a8 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -264,11 +264,13 @@ public function register(): void For more information you can check the ["CanModify" and "CanCustomize" traits in `./app/Traits/Filament`](https://github.com/pelican-dev/panel/tree/main/app/Traits/Filament). -### Add new role permissions +### Add new permissions -To add new (admin) role permissions you can use `Role::registerCustomPermissions` and `Role::registerCustomDefaultPermissions`. You can call these static methods inside the `register` function of a service provider. +#### Admin Roles -Examples: +To add new admin role permissions you can use `Role::registerCustomPermissions` and `Role::registerCustomDefaultPermissions`. + +You can call these static methods inside the `register` function of a service provider. Examples: ```php title="MyPluginProvider.php" public function register(): void @@ -296,9 +298,22 @@ public function register(): void } ``` - - This will only work for admin role permissions, not subuser permissions! There is currently no way to register custom subuser permissions. - +#### Subuser + +To add new subuser permissions you can use `Subuser::registerCustomPermissions`. + +You can call this static method inside the `register` function of a service provider. Examples: + +```php title="MyPluginProvider.php" +public function register(): void +{ + // Register new subuser permissions (call with icon and hidden param) + Subuser::registerCustomPermissions('custom', ['customPerm1', 'customPerm2'], 'tabler-star', false); + + // You can also add new permissions to existing permission groups (call without icon and hidden param) + Subuser::registerCustomPermissions('console', ['custom']); +} +``` ## Publish a Plugin From df5cfd79b7dff51047d3f92518ee48a7e955d509 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Fri, 12 Dec 2025 10:16:06 +0100 Subject: [PATCH 14/15] add info about running artisan commands inside the panel dir --- docs/panel/advanced/plugins.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index 1aa1c0a8..266c03d1 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -17,7 +17,7 @@ Plugins allow you to add new functionality to the panel without modifying any pa Use the Import Button on the plugin list to upload & install a plugin. - Move the plugin folder to `/var/www/pelican/plugins`. Then run `php artisan p:plugin:install` and select the new plugin. + Move the plugin folder to `plugins` inside your panel directory (`/var/www/pelican/plugins` by default). Then run `php artisan p:plugin:install` inside your panel directory and select the new plugin. @@ -32,7 +32,7 @@ Plugins allow you to add new functionality to the panel without modifying any pa You **need** at least basic [PHP](https://php.net), [Laravel](https://laravel.com) and [Filament](https://filamentphp.com) knowledge to create plugins! -Run `php artisan p:plugin:make` to create the basic files and folders for your new plugin. This will create the `plugin.json`, the main plugin file, a config file and a service provider. +Run `php artisan p:plugin:make` inside your panel directory (`/var/www/pelican` by default) to create the basic files and folders for your new plugin. This will create the `plugin.json`, the main plugin file, a config file and a service provider. Visit our [Discord](https://discord.gg/pelican-panel) if you need any help when creating plugins! From 44dda12c4ee520f061f4e8b10067d14d9241a4d2 Mon Sep 17 00:00:00 2001 From: Boy132 Date: Fri, 12 Dec 2025 10:34:17 +0100 Subject: [PATCH 15/15] add info about seeder --- docs/panel/advanced/plugins.mdx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/panel/advanced/plugins.mdx b/docs/panel/advanced/plugins.mdx index 266c03d1..06fc0aee 100644 --- a/docs/panel/advanced/plugins.mdx +++ b/docs/panel/advanced/plugins.mdx @@ -202,6 +202,11 @@ If your plugin adds new default languages to the panel you need to set the plugi Views are automatically registered under the namespace of your plugin. This means you need to prefix view-strings with your plugin id, e.g. `myplugin::my-view` would look for `plugins/myplugin/resources/views/my-view.blade.php`. +### Seeder + +If present, a seeder with the name of your plugin will be automatically registered. It needs to be named `Seeder` (e.g. `MyPluginSeeder`) and put inside your plugins `database/Seeder` folder, e.g. `plugins/myplugin/database/Seeder/MyPluginSeeder.php`. +This seeder will be automatically called when a user installs the plugin or when seeders are run in general, e.g. when using `php artisan db:seed` or `php artisan migrate --seed`. + ### Plugin Settings Your main plugin class can implement the `HasPluginSettings` interface to conveniently add a settings page to your plugin.