pelican-panel-plugins
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePelican Panel Plugins
Pelican面板插件
Pelican is an open-source game server management panel built on Laravel + FilamentPHP. Plugins let you add functionality without touching core files.
⚠️ The plugin system is still in active development — some features may change.
Pelican是一款基于Laravel + FilamentPHP构建的开源游戏服务器管理面板。通过插件,你无需修改核心文件即可添加功能。
⚠️ 插件系统仍在积极开发中——部分功能可能会发生变更。
Quick Reference
快速参考
📖 Detailed Guides:
- FilamentPHP Patterns - Resources, pages, widgets, actions, relation managers
- Advanced Patterns - Models, services, routes, commands, events
- Complete Plugin Walkthrough - Step-by-step example
📖 详细指南:
- FilamentPHP模式 - 资源、页面、小部件、操作、关联管理器
- 进阶模式 - 模型、服务、路由、命令、事件
- 完整插件开发教程 - 分步示例
Scaffolding a New Plugin
搭建新插件
Run inside the panel directory ( by default):
/var/www/pelicanbash
php artisan p:plugin:makeThis creates the basic structure with , main plugin class, service provider, and config file.
plugin.jsonCritical: The plugin folder name must exactly match thefield inid.plugin.json
在面板目录(默认路径为)内运行:
/var/www/pelicanbash
php artisan p:plugin:make此命令会创建包含、主插件类、服务提供者和配置文件的基础结构。
plugin.json重要提示: 插件文件夹名称必须与中的plugin.json字段完全匹配。id
Plugin Structure
插件结构
plugins/my-plugin/
├── plugin.json # Metadata and configuration
├── config/
│ └── my-plugin.php # Config values (use env vars)
├── database/
│ └── migrations/ # Auto-discovered migrations
├── lang/ # Translations (namespaced: my-plugin::strings.key)
├── resources/
│ └── views/ # Blade views (namespaced: my-plugin::view-name)
├── routes/ # Optional route files
└── src/ # App logic (PSR-4 autoloaded)
├── MyPlugin.php # Main plugin class
├── Filament/
│ ├── Admin/ # Admin panel components
│ │ ├── Pages/
│ │ ├── Resources/
│ │ └── Widgets/
│ ├── App/ # Server list panel
│ └── Server/ # Server management panel
├── Models/
├── Policies/ # Auto-discovered
├── Providers/ # Auto-discovered service providers
├── Console/Commands/ # Auto-discovered artisan commands
└── Http/
└── Controllers/Everything in standard Laravel locations is auto-discovered: migrations, providers, commands, policies.
plugins/my-plugin/
├── plugin.json # 元数据与配置
├── config/
│ └── my-plugin.php # 配置值(使用环境变量)
├── database/
│ └── migrations/ # 自动发现的迁移文件
├── lang/ # 翻译文件(命名空间:my-plugin::strings.key)
├── resources/
│ └── views/ # Blade视图(命名空间:my-plugin::view-name)
├── routes/ # 可选路由文件
└── src/ # 应用逻辑(PSR-4自动加载)
├── MyPlugin.php # 主插件类
├── Filament/
│ ├── Admin/ # 管理面板组件
│ │ ├── Pages/
│ │ ├── Resources/
│ │ └── Widgets/
│ ├── App/ # 服务器列表面板
│ └── Server/ # 服务器管理面板
├── Models/
├── Policies/ # 自动发现
├── Providers/ # 自动发现的服务提供者
├── Console/Commands/ # 自动发现的Artisan命令
└── Http/
└── Controllers/标准Laravel目录下的所有内容都会被自动发现:迁移文件、服务提供者、命令、策略。
plugin.json
plugin.json
json
{
"id": "my-plugin",
"name": "My Plugin",
"author": "Your Name",
"version": "1.0.0",
"description": "Short description",
"category": "plugin",
"namespace": "MyName\\MyPlugin",
"class": "MyPlugin",
"panels": ["admin", "server"],
"panel_version": "^1.2.0",
"composer_packages": {
"vendor/package": "^1.0"
}
}| Field | Required | Notes |
|---|---|---|
| ✅ | Must match folder name |
| ✅ | PHP namespace root (use |
| ✅ | Main class name (in |
| ✅ | |
| No | Array of panel IDs or omit for all panels |
| No | Minimum panel version (e.g., |
| No | External dependencies |
json
{
"id": "my-plugin",
"name": "My Plugin",
"author": "Your Name",
"version": "1.0.0",
"description": "Short description",
"category": "plugin",
"namespace": "MyName\\MyPlugin",
"class": "MyPlugin",
"panels": ["admin", "server"],
"panel_version": "^1.2.0",
"composer_packages": {
"vendor/package": "^1.0"
}
}| 字段 | 是否必填 | 说明 |
|---|---|---|
| ✅ | 必须与文件夹名称匹配 |
| ✅ | PHP命名空间根目录(使用 |
| ✅ | 主类名称(位于 |
| ✅ | 可选值: |
| 否 | 面板ID数组,省略则适配所有面板 |
| 否 | 最低面板版本要求(例如: |
| 否 | 外部依赖包 |
Main Plugin Class
主插件类
Located in :
src/{ClassName}.phpphp
namespace MyName\MyPlugin;
use Filament\Contracts\Plugin;
use Filament\Panel;
class MyPlugin implements Plugin
{
public function getId(): string
{
return 'my-plugin';
}
public function register(Panel $panel): void
{
$id = str($panel->getId())->title(); // "Admin", "App", "Server"
// Auto-discover Filament components
$panel->discoverPages(
plugin_path($this->getId(), "src/Filament/$id/Pages"),
"MyName\\MyPlugin\\Filament\\$id\\Pages"
);
$panel->discoverResources(
plugin_path($this->getId(), "src/Filament/$id/Resources"),
"MyName\\MyPlugin\\Filament\\$id\\Resources"
);
$panel->discoverWidgets(
plugin_path($this->getId(), "src/Filament/$id/Widgets"),
"MyName\\MyPlugin\\Filament\\$id\\Widgets"
);
}
public function boot(Panel $panel): void
{
//
}
}位于:
src/{ClassName}.phpphp
namespace MyName\MyPlugin;
use Filament\Contracts\Plugin;
use Filament\Panel;
class MyPlugin implements Plugin
{
public function getId(): string
{
return 'my-plugin';
}
public function register(Panel $panel): void
{
$id = str($panel->getId())->title(); // "Admin", "App", "Server"
// 自动发现Filament组件
$panel->discoverPages(
plugin_path($this->getId(), "src/Filament/$id/Pages"),
"MyName\\MyPlugin\\Filament\\$id\\Pages"
);
$panel->discoverResources(
plugin_path($this->getId(), "src/Filament/$id/Resources"),
"MyName\\MyPlugin\\Filament\\$id\\Resources"
);
$panel->discoverWidgets(
plugin_path($this->getId(), "src/Filament/$id/Widgets"),
"MyName\\MyPlugin\\Filament\\$id\\Widgets"
);
}
public function boot(Panel $panel): void
{
//
}
}The Three Filament Panels
三个Filament面板
| Panel ID | Area | Use Case |
|---|---|---|
| Admin area | Full CRUD for resources, settings, management |
| Server list | Minimal UI (no nav by default) |
| Server management | Tenant-scoped (current server context) |
| 面板ID | 区域 | 使用场景 |
|---|---|---|
| 管理后台 | 资源的完整CRUD操作、设置、管理功能 |
| 服务器列表 | 极简UI(默认无导航) |
| 服务器管理 | 租户范围(当前服务器上下文) |
Enabling Navigation on app
Panel
app在app
面板启用导航
appphp
use App\Filament\App\Resources\Servers\ServerResource;
use App\Enums\CustomizationKey;
public function register(Panel $panel): void
{
parent::register($panel);
if ($panel->getId() === 'app') {
ServerResource::embedServerList();
$panel->navigation(true);
$panel->topbar(function () {
$nav = user()?->getCustomization(CustomizationKey::TopNavigation);
return in_array($nav, ['topbar', 'mixed', true], true);
});
$panel->clearCachedComponents();
}
}php
use App\Filament\App\Resources\Servers\ServerResource;
use App\Enums\CustomizationKey;
public function register(Panel $panel): void
{
parent::register($panel);
if ($panel->getId() === 'app') {
ServerResource::embedServerList();
$panel->navigation(true);
$panel->topbar(function () {
$nav = user()?->getCustomization(CustomizationKey::TopNavigation);
return in_array($nav, ['topbar', 'mixed', true], true);
});
$panel->clearCachedComponents();
}
}Extending Core Resources
扩展核心资源
Call static methods on core classes inside a service provider's :
register()php
use App\Filament\Admin\Resources\Users\UserResource;
use App\Filament\Admin\Resources\Servers\ServerResource;
use App\Models\Role;
public function register(): void
{
// Add a relation manager tab
ServerResource::registerCustomRelations(MyRelationManager::class);
// Register permissions
Role::registerCustomDefaultPermissions('myModel');
Role::registerCustomModelIcon('myModel', 'tabler-star');
}Available customization traits (check for all):
app/Traits/Filament/- - Relation managers, custom actions
CanModifyResource - - Widgets, header actions
CanCustomizePage - /
CanModifyForm- Form/table hooksCanModifyTable
在服务提供者的方法中调用核心类的静态方法:
register()php
use App\Filament\Admin\Resources\Users\UserResource;
use App\Filament\Admin\Resources\Servers\ServerResource;
use App\Models\Role;
public function register(): void
{
// 添加关联管理器标签页
ServerResource::registerCustomRelations(MyRelationManager::class);
// 注册权限
Role::registerCustomDefaultPermissions('myModel');
Role::registerCustomModelIcon('myModel', 'tabler-star');
}可用的自定义特性(查看获取全部):
app/Traits/Filament/- - 关联管理器、自定义操作
CanModifyResource - - 小部件、头部操作
CanCustomizePage - /
CanModifyForm- 表单/表格钩子CanModifyTable
Plugin Settings
插件设置
Implement on your main class:
HasPluginSettingsphp
use App\Contracts\Plugins\HasPluginSettings;
use App\Traits\EnvironmentWriterTrait;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
class MyPlugin implements Plugin, HasPluginSettings
{
use EnvironmentWriterTrait;
public function getSettingsForm(): array
{
return [
TextInput::make('api_key')
->required()
->default(fn () => config('my-plugin.api_key')),
];
}
public function saveSettings(array $data): void
{
$this->writeToEnvironment([
'MY_PLUGIN_API_KEY' => $data['api_key'],
]);
Notification::make()->title('Settings saved')->success()->send();
}
}Always prefix env vars with your plugin ID to avoid conflicts.
在主类中实现接口:
HasPluginSettingsphp
use App\Contracts\Plugins\HasPluginSettings;
use App\Traits\EnvironmentWriterTrait;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
class MyPlugin implements Plugin, HasPluginSettings
{
use EnvironmentWriterTrait;
public function getSettingsForm(): array
{
return [
TextInput::make('api_key')
->required()
->default(fn () => config('my-plugin.api_key')),
];
}
public function saveSettings(array $data): void
{
$this->writeToEnvironment([
'MY_PLUGIN_API_KEY' => $data['api_key'],
]);
Notification::make()->title('Settings saved')->success()->send();
}
}环境变量请始终以插件ID作为前缀,避免冲突。
Permissions
权限
Admin Role Permissions
管理员角色权限
In your service provider's :
register()php
use App\Models\Role;
// Shorthand: registers viewList, view, create, update, delete
Role::registerCustomDefaultPermissions('myModel');
// Custom permissions
Role::registerCustomPermissions([
'myModel' => ['export', 'approve'],
'server' => ['customAction'], // extend existing model
]);
// Optional: icon for permission group
Role::registerCustomModelIcon('myModel', 'tabler-star');在服务提供者的方法中:
register()php
use App\Models\Role;
// 简写方式:注册viewList、view、create、update、delete权限
Role::registerCustomDefaultPermissions('myModel');
// 自定义权限
Role::registerCustomPermissions([
'myModel' => ['export', 'approve'],
'server' => ['customAction'], // 扩展现有模型
]);
// 可选:为权限组设置图标
Role::registerCustomModelIcon('myModel', 'tabler-star');Subuser Permissions
子用户权限
php
use App\Models\Subuser;
// New permission group
Subuser::registerCustomPermissions('myFeature', ['read', 'write'], 'tabler-bolt', false);
// Append to existing group
Subuser::registerCustomPermissions('console', ['myCustomAction']);php
use App\Models\Subuser;
// 新增权限组
Subuser::registerCustomPermissions('myFeature', ['read', 'write'], 'tabler-bolt', false);
// 添加到现有权限组
Subuser::registerCustomPermissions('console', ['myCustomAction']);Routes
路由
Create a in :
RouteServiceProvidersrc/Providers/php
use Illuminate\Foundation\Support\Providers\RouteServiceProvider;
use Illuminate\Support\Facades\Route;
class MyPluginRoutesProvider extends RouteServiceProvider
{
public function boot(): void
{
$this->routes(function () {
// Simple route
Route::get('/my-plugin/test', [TestController::class, 'index'])
->name('my-plugin.test');
// Load from file
Route::prefix('/my-plugin')
->group(plugin_path('my-plugin', 'routes/web.php'));
// Append to client API
Route::middleware(['api', 'client-api', 'throttle:api.client'])
->prefix('/api/client/servers/{server}')
->scopeBindings()
->group(plugin_path('my-plugin', 'routes/api-client.php'));
});
}
}在目录下创建:
src/Providers/RouteServiceProviderphp
use Illuminate\Foundation\Support\Providers\RouteServiceProvider;
use Illuminate\Support\Facades\Route;
class MyPluginRoutesProvider extends RouteServiceProvider
{
public function boot(): void
{
$this->routes(function () {
// 简单路由
Route::get('/my-plugin/test', [TestController::class, 'index'])
->name('my-plugin.test');
// 从文件加载路由
Route::prefix('/my-plugin')
->group(plugin_path('my-plugin', 'routes/web.php'));
// 添加到客户端API
Route::middleware(['api', 'client-api', 'throttle:api.client'])
->prefix('/api/client/servers/{server}')
->scopeBindings()
->group(plugin_path('my-plugin', 'routes/api-client.php'));
});
}
}Models & Relationships
模型与关联
Add Relationship to Core Models
为核心模型添加关联
In your service provider's :
boot()php
use App\Models\Server;
use MyPlugin\Models\Ticket;
public function boot(): void
{
Server::resolveRelationUsing('tickets', fn (Server $server) =>
$server->hasMany(Ticket::class, 'server_id', 'id')
);
}Now works everywhere.
$server->tickets在服务提供者的方法中:
boot()php
use App\Models\Server;
use MyPlugin\Models\Ticket;
public function boot(): void
{
Server::resolveRelationUsing('tickets', fn (Server $server) =>
$server->hasMany(Ticket::class, 'server_id', 'id')
);
}现在可在任何地方使用。
$server->ticketsPolicies
策略
php
use App\Policies\DefaultAdminPolicies;
class MyModelPolicy
{
use DefaultAdminPolicies;
protected string $modelName = 'myModel';
}This automatically checks admin role permissions based on the registered model name.
php
use App\Policies\DefaultAdminPolicies;
class MyModelPolicy
{
use DefaultAdminPolicies;
protected string $modelName = 'myModel';
}这会基于已注册的模型名称自动检查管理员角色权限。
Translations
翻译
Place in (e.g., ):
lang/{locale}/lang/en/strings.phpphp
return [
'welcome' => 'Welcome',
'item' => 'Item|Items', // Pluralization
];Usage:
php
trans('my-plugin::strings.welcome')
trans_choice('my-plugin::strings.item', 2) // "Items"将翻译文件放置在目录下(例如:):
lang/{locale}/lang/en/strings.phpphp
return [
'welcome' => 'Welcome',
'item' => 'Item|Items', // 复数形式
];使用方式:
php
trans('my-plugin::strings.welcome')
trans_choice('my-plugin::strings.item', 2) // "Items"Views
视图
Place in :
resources/views/php
view('my-plugin::my-view')
// → plugins/my-plugin/resources/views/my-view.blade.php将视图文件放置在目录下:
resources/views/php
view('my-plugin::my-view')
// → plugins/my-plugin/resources/views/my-view.blade.phpCommon Patterns
常见模式
FilamentPHP Components
FilamentPHP组件
See FilamentPHP Patterns for:
- Resources (CRUD interfaces)
- Pages (custom pages)
- Widgets (dashboard components)
- Relation Managers (manage related records)
- Custom Actions (reusable buttons)
- Form components (inputs, selects, toggles)
- Table columns and filters
查看FilamentPHP模式了解:
- 资源(CRUD界面)
- 页面(自定义页面)
- 小部件(仪表盘组件)
- 关联管理器(管理关联记录)
- 自定义操作(可复用按钮)
- 表单组件(输入框、选择器、开关)
- 表格列与过滤器
Advanced Patterns
进阶模式
See Advanced Patterns for:
- Model events and hooks
- Enums with Filament interfaces
- Service classes
- HTTP controllers and API routes
- Artisan commands and scheduling
- HTTP macros for external APIs
- Database migrations
- Error handling
查看进阶模式了解:
- 模型事件与钩子
- 支持Filament接口的枚举
- 服务类
- HTTP控制器与API路由
- Artisan命令与调度
- 用于外部API的HTTP宏
- 数据库迁移
- 错误处理
Complete Example
完整示例
See Complete Plugin Walkthrough for a step-by-step guide building a "Server Notes" plugin.
查看完整插件开发教程,了解分步构建“服务器笔记”插件的过程。
Publishing a Plugin
发布插件
- Open and remove the
plugin.jsonblock (internal use only)meta - Zip the entire plugin folder
- Share the zip — users install via panel UI Import button or manually drop into
plugins/
Publish to the community:
- GitHub: pelican-dev/plugins
- Discord: channel at discord.gg/pelican-panel
#plugins
- 打开并移除
plugin.json块(仅内部使用)meta - 将整个插件文件夹压缩为ZIP包
- 分享ZIP包——用户可通过面板UI的导入按钮安装,或手动将其放入目录
plugins/
发布到社区:
- GitHub: pelican-dev/plugins
- Discord: 加入discord.gg/pelican-panel的频道
#plugins
Tips & Gotchas
提示与注意事项
- Namespace in plugin.json: Use (double backslash) for namespace separators
\\ - Migration naming: Use numeric prefixes (,
001_) to control execution order002_ - Environment variables: Always prefix with your plugin ID (e.g., )
MY_PLUGIN_* - Panel context: Use to get current server in server panel
Filament::getTenant() - Auto-discovery: Service providers, commands, migrations, and policies are auto-discovered
- Relation managers: Must be registered on core resources via in service provider's
registerCustomRelations()methodregister() - Testing: Use to reset and test migrations
php artisan migrate:fresh --seed - Permissions: Register in service provider's , not
register()boot()
- plugin.json中的命名空间:使用(双反斜杠)作为命名空间分隔符
\\ - 迁移文件命名:使用数字前缀(、
001_)控制执行顺序002_ - 环境变量:始终以插件ID作为前缀(例如:)
MY_PLUGIN_* - 面板上下文:在服务器面板中使用获取当前服务器
Filament::getTenant() - 自动发现:服务提供者、命令、迁移文件和策略会被自动发现
- 关联管理器:必须在服务提供者的方法中通过
register()注册到核心资源registerCustomRelations() - 测试:使用重置并测试迁移
php artisan migrate:fresh --seed - 权限:在服务提供者的方法中注册,而非
register()boot()
Getting Help
获取帮助
- Documentation: pelican.dev/docs/panel
- Discord: discord.gg/pelican-panel
- GitHub: github.com/pelican-dev/panel
- Example Plugins: github.com/pelican-dev/plugins
- 文档:pelican.dev/docs/panel
- Discord:discord.gg/pelican-panel
- GitHub:github.com/pelican-dev/panel
- 示例插件:github.com/pelican-dev/plugins