Waravel Plugin Template
This is a complete template for creating a new Waravel plugin. Copy this structure and customize it for your plugin.
📁 Directory Structure
plugins/
└── YourPluginName/
├── plugin.json
├── YourPluginNamePlugin.php
├── Controllers/
│ └── YourPluginController.php
├── Services/
│ └── YourPluginService.php
├── Models/
│ └── YourPluginModel.php
├── database/
│ └── migrations/
│ └── 2024_01_01_000000_create_your_plugin_table.php
├── resources/
│ └── views/
│ └── dashboard/
│ ├── index.blade.php
│ ├── details.blade.php
│ └── settings.blade.php
└── README.md📄 File Templates
1. plugin.json
json
{
"name": "Your Plugin Name",
"version": "1.0.0",
"description": "Brief description of your plugin functionality",
"author": "Your Name",
"author_email": "[email protected]",
"plugin_url": "https://yourwebsite.com/plugin",
"plugin_namespace": "YourPluginNamespace",
"dependencies": [],
"permissions": [
"your_permission_name"
],
"settings": {
"setting_key": {
"type": "text",
"label": "Setting Label",
"description": "Setting description",
"required": true,
"default": "default_value"
},
"enable_feature": {
"type": "boolean",
"label": "Enable Feature",
"description": "Enable this feature",
"default": false
}
},
"hooks": {
"hook_name": "YourPluginNamespace\\Hooks\\HookClass"
}
}2. YourPluginNamePlugin.php
php
<?php
namespace YourPluginNamespace;
use Sobberrc\Waravel\Plugins\Plugin;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\View;
// Global guard to prevent multiple plugin loading
if (defined('YOUR_PLUGIN_LOADED')) {
return;
}
define('YOUR_PLUGIN_LOADED', true);
class YourPluginNamePlugin extends Plugin
{
public function __construct()
{
parent::__construct();
}
protected function initializePlugin(): void
{
$this->name = 'Your Plugin Name';
$this->version = '1.0.0';
$this->description = 'Brief description of your plugin functionality';
$this->author = 'Your Name';
$this->authorEmail = '[email protected]';
$this->pluginUrl = 'https://yourwebsite.com/plugin';
$this->pluginNamespace = 'YourPluginNamespace';
$this->dependencies = [];
$this->permissions = ['your_permission_name'];
}
private static $booted = false;
private static $bootInProgress = false;
public function boot(): void
{
if (self::$booted || self::$bootInProgress) {
return;
}
self::$bootInProgress = true;
try {
$this->registerRoutes();
$this->registerViews();
self::$booted = true;
} catch (\Exception $e) {
\Log::error('Your Plugin Name: Boot failed - ' . $e->getMessage());
} finally {
self::$bootInProgress = false;
}
}
protected function registerRoutes(): void
{
Route::middleware(['web', 'auth:waravel'])
->prefix('waravel/plugins/your-plugin-name')
->name('waravel.plugins.your-plugin-name.')
->group(function () {
Route::get('/', [\YourPluginNamespace\Controllers\YourPluginController::class, 'index'])->name('index');
Route::get('/details', [\YourPluginNamespace\Controllers\YourPluginController::class, 'details'])->name('details');
Route::get('/settings', [\YourPluginNamespace\Controllers\YourPluginController::class, 'settings'])->name('settings');
Route::post('/settings', [\YourPluginNamespace\Controllers\YourPluginController::class, 'updateSettings'])->name('settings.update');
});
}
protected function registerViews(): void
{
View::addNamespace('your-plugin-namespace', __DIR__ . '/resources/views');
}
protected function onInstall(): void
{
// Create database tables if needed
$this->createTables();
}
protected function onActivate(): void
{
// Plugin activated - ensure tables exist
$this->createTables();
}
protected function onDeactivate(): void
{
// Plugin deactivated
}
protected function onUninstall(bool $keepData = false): void
{
if (!$keepData) {
// Drop plugin tables
$this->dropTables();
}
}
private function createTables(): void
{
// Run migrations
\Artisan::call('migrate', [
'--path' => 'plugins/YourPluginName/database/migrations',
'--force' => true
]);
}
private function dropTables(): void
{
// Drop plugin tables
\DB::statement('DROP TABLE IF EXISTS your_plugin_table');
}
}3. Controllers/YourPluginController.php
php
<?php
namespace YourPluginNamespace\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\View\View;
class YourPluginController
{
public function index(): View
{
return view('your-plugin-namespace::dashboard.index');
}
public function details(): View
{
$plugin = $this->getPlugin();
return view('your-plugin-namespace::dashboard.details', compact('plugin'));
}
public function settings(): View
{
$plugin = $this->getPlugin();
$settings = $this->getPluginSettings();
return view('your-plugin-namespace::dashboard.settings', compact('plugin', 'settings'));
}
public function updateSettings(Request $request): JsonResponse
{
try {
$settings = $request->input('settings', []);
// Update plugin settings
foreach ($settings as $key => $value) {
\DB::table('waravel_plugin_settings')
->updateOrInsert(
['plugin_name' => $this->getPluginName(), 'setting_key' => $key],
['setting_value' => $value, 'updated_at' => now()]
);
}
return response()->json([
'success' => true,
'message' => 'Settings updated successfully'
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'Failed to update settings: ' . $e->getMessage()
], 500);
}
}
private function getPlugin()
{
return \DB::table('waravel_plugins')
->where('name', $this->getPluginName())
->first();
}
private function getPluginName(): string
{
return 'Your Plugin Name';
}
private function getPluginSettings(): array
{
$settings = \DB::table('waravel_plugin_settings')
->where('plugin_name', $this->getPluginName())
->pluck('setting_value', 'setting_key')
->toArray();
return $settings;
}
}4. Services/YourPluginService.php
php
<?php
namespace YourPluginNamespace\Services;
class YourPluginService
{
public function processData(array $data): array
{
// Your business logic here
return $data;
}
public function validateSettings(array $settings): array
{
$errors = [];
// Validate settings
if (isset($settings['required_field']) && empty($settings['required_field'])) {
$errors[] = 'Required field cannot be empty';
}
return $errors;
}
}5. Models/YourPluginModel.php
php
<?php
namespace YourPluginNamespace\Models;
use Illuminate\Database\Eloquent\Model;
class YourPluginModel extends Model
{
protected $table = 'your_plugin_table';
protected $fillable = [
'name',
'data',
'status'
];
protected $casts = [
'data' => 'array'
];
}6. database/migrations/2024_01_01_000000_create_your_plugin_table.php
php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('your_plugin_table', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->json('data')->nullable();
$table->string('status')->default('active');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('your_plugin_table');
}
};7. resources/views/dashboard/index.blade.php
php
@extends('waravel::layouts.dashboard-layouts.dashboard-base')
@section('content')
<div class="p-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h2 class="text-2xl font-bold text-gray-800 mb-4">Your Plugin Name</h2>
<div class="space-y-4">
<p class="text-gray-600">Welcome to your plugin! This is the main interface.</p>
<!-- Your plugin's main functionality here -->
<div class="bg-blue-50 p-4 rounded-lg">
<h3 class="text-lg font-semibold text-blue-800 mb-2">Quick Actions</h3>
<div class="space-x-2">
<button class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">
Action 1
</button>
<button class="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600">
Action 2
</button>
</div>
</div>
</div>
</div>
</div>
@endsection8. resources/views/dashboard/details.blade.php
php
@extends('waravel::layouts.dashboard-layouts.dashboard-base')
@section('content')
<div class="p-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h2 class="text-2xl font-bold text-gray-800 mb-4">Plugin Details</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<h3 class="text-lg font-semibold mb-2">Plugin Information</h3>
<table class="w-full">
<tr><td class="font-medium">Name:</td><td>{{ $plugin->name }}</td></tr>
<tr><td class="font-medium">Version:</td><td>{{ $plugin->version }}</td></tr>
<tr><td class="font-medium">Author:</td><td>{{ $plugin->author }}</td></tr>
<tr><td class="font-medium">Status:</td><td>{{ $plugin->active ? 'Active' : 'Inactive' }}</td></tr>
</table>
</div>
<div>
<h3 class="text-lg font-semibold mb-2">Description</h3>
<p class="text-gray-600">{{ $plugin->description }}</p>
</div>
</div>
<div class="mt-6">
<h3 class="text-lg font-semibold mb-2">Features</h3>
<ul class="list-disc list-inside space-y-1 text-gray-600">
<li>Feature 1</li>
<li>Feature 2</li>
<li>Feature 3</li>
</ul>
</div>
</div>
</div>
@endsection9. resources/views/dashboard/settings.blade.php
php
@extends('waravel::layouts.dashboard-layouts.dashboard-base')
@section('content')
<div class="p-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h2 class="text-2xl font-bold text-gray-800 mb-4">Plugin Settings</h2>
<form id="settingsForm" method="POST" action="{{ route('waravel.plugins.your-plugin-name.settings.update') }}">
@csrf
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Setting Label
</label>
<input type="text" name="settings[setting_key]"
value="{{ $settings['setting_key'] ?? '' }}"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<p class="text-sm text-gray-500 mt-1">Setting description</p>
</div>
<div>
<label class="flex items-center">
<input type="checkbox" name="settings[enable_feature]" value="1"
{{ ($settings['enable_feature'] ?? false) ? 'checked' : '' }}
class="mr-2">
<span class="text-sm font-medium text-gray-700">Enable Feature</span>
</label>
<p class="text-sm text-gray-500 mt-1">Enable this feature</p>
</div>
</div>
<div class="flex justify-end mt-6">
<button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded-md hover:bg-blue-600">
Save Settings
</button>
</div>
</form>
</div>
</div>
<script>
document.getElementById('settingsForm').addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
fetch(this.action, {
method: 'POST',
body: formData,
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('Settings saved successfully!');
} else {
alert('Error: ' + data.message);
}
})
.catch(error => {
alert('Error saving settings: ' + error.message);
});
});
</script>
@endsection10. README.md
markdown
# Your Plugin Name
## Description
Brief description of your plugin functionality.
## Installation
1. Copy the plugin directory to `plugins/YourPluginName/`
2. The plugin will be automatically detected by Waravel
3. Activate the plugin from the Waravel dashboard
## Usage
1. Go to the Waravel dashboard
2. Navigate to Plugins
3. Find your plugin and click "Start"
4. Configure settings as needed
## Features
- Feature 1
- Feature 2
- Feature 3
## Requirements
- Waravel package
- PHP 8.2+
- Laravel 10+
## Support
For support and questions, please contact [[email protected]]
## License
[Your License]🚀 Getting Started
- Copy this template to
plugins/YourPluginName/ - Replace placeholders with your actual plugin details
- Customize the functionality according to your needs
- Test your plugin thoroughly
- Document your plugin in README.md
📝 Customization Checklist
- [ ] Update
plugin.jsonwith your plugin details - [ ] Rename
YourPluginNamePlugin.phpto match your plugin - [ ] Update namespace in all PHP files
- [ ] Customize the main view (
index.blade.php) - [ ] Customize the details view (
details.blade.php) - [ ] Customize the settings view (
settings.blade.php) - [ ] Implement your business logic in Services
- [ ] Create your database models
- [ ] Add your database migrations
- [ ] Test all functionality
- [ ] Update README.md
Happy plugin development! 🎉