winkelco / laravel-extension
Plugin, Extension and Module System For Laravel
Installs: 2 655
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 2
Forks: 0
Open Issues: 0
Requires
- php: ^7.0|^8.0
- illuminate/support: ^7|^8|^9
Requires (Dev)
- phpunit/phpunit: ^8.0|^9.0
README
Plugin, Extension and Module System For Laravel. Inspirate from Wordpress Plugins.
Table of contents
- Installing
- Extension Management Page
- Extension Folder Structure
- Create New Extension
- Hook
- Menu Builder
- Unit Test
- Examples
- License
Installing
Install from composer :
composer require winkelco/laravel-extension
We make this package with Auto Discovery, but you can add manual :
# service provider :
WinkelCo\LaravelExtension\LaravelExtensionServiceProvider::class
# aliases
"Extension" => WinkelCo\LaravelExtension\Facades\Extension::class,
"Hook" => WinkelCo\LaravelExtension\Facades\Hook::class
Publish Config :
php artisan vendor:publish --provider="WinkelCo\LaravelExtension\LaravelExtensionServiceProvider"
Added Namespace To Your Composer : (edit your laravel composer.json
)
"autoload": {
"psr-4": {
"App\\": "app/",
"Extension\\": "app/Extension/",
},
},
And then, you can generate composer autoload :
composer dump-autoload
For first time after installing, you must run this command for generate extension folder in app\Extension
:
php artisan extension:init
Extension Management Page
For a simple Extension management page, added this route to your rourtes routes/web.php
:
use WinkelCo\LaravelExtension\Facades\Extension;
Extension::routes();
Save, and then access in your browser http://mylaravelproject.test/extension
or 'localhost:8000/extension`, and finaly, you see this page :
Extension Folder Structure
By Default, Extension path in app/Extension
, you can create Extension in this folder.
. app
├── Console
├── Exceptions
├── Extension
│ ├── ExampleExtension
│ │ └── extension.json
│ │ └── ServiceProvider.php
│ ├── MyExtension
│ │ ├── extension.json
│ │ └── MyExtensionServiceProvider.php
│ └── extension.json
├── Http
├── Providers
├── User.php
Artisan Console Command Support
Make new extension easy :
php artisan extension:new ExampleExtension
Update list installed extension :
php artisan extension:update-list
Get list installed extension :
php artisan extension:list
Enable a extension : (plugin must be added in list first)
php artisan extension:enable ExamplePlugin
Disable a extension :
php artisan extension:disable ExamplePlugin
Inspect a Extension
php artisan extension:inspect ExamplePlugin
Get Hook list (all)
php artisan hook:list
Get Hook list specific type (action or filter)
# only action :
php artisan hook:list --action
# only filter :
php artisan hook:list --filter
Create New Extension
with Artisan Command
you can create new extension with this command :
php artisan extension:new ExampleTes
after success, you can refresh extension list with :
php artisan extension:update-list
and you can check if updating list success :
php artisan extension:list
for enable your extension, use :
php artisan extension:enable ExampleTes
Manual
| note : this use indonesian language, you can translate this.
Lokasi extension harus ada pada folder utama extension, secara default
ada pada app\Extension
. berikut panduan singkat cara pembuatan extension :
- membuat folder utama extension, misal
app\Extension\MyPlugin
- buat file config untuk plugin anda di
app\Extension\MyPlugin\extension.json
, isi dengan :
{
"name": "My Example Plugin",
"description": "describe your extension.",
"version": "1.0.0",
"provider": "MyPluginServiceProvider",
"author": {
"name": "winkelco",
"site": "https://github.com/winkelco"
}
}
- Buat service provider untuk extension anda, di folder working extension tadi, sebagai contoh
app\Extension\MyPlugin\MyPluginServiceProvider.php
isinya :
<?php
namespace Extension\MyPlugin;
use WinkelCo\LaravelExtension\Support\ServiceProvider;
class MyPluginServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
//
}
}
- Sekarang, jalankan perintah ini diartisan untuk mengupdate list extension yang terinstall di
app\Extension\extension.json
:
php artisan extension:update-list
anda bisa menambahkanya otomatis di file config app\Extension\extension.json
, jika anda menjalankan perintah diatas, perintah tersebut akan otomatis mengupdate daftar extension anda yang ada di app\Extension\extension.json
, seharusnya menjadi seperti berikut nantinya file app\Extension\extension.json
:
{
"list": [
"MyPlugin"
],
"active": []
}
- Cek apakah extension tersebut sudah terdaftar dengan menjalankan perintah :
php artisan extension:list
- jika terdaftar tapi statusnya belum
active
, silahkan jalankan perintah :
php artisan extension:enable MyPlugin
Hook
Action
with Hook Action, you can make multi-action system and management action.
Make Action :
Hook::addAction(string $extension, string $name, \Closure $callback, int $priority = 10)
Run Action :
Hook::runAction(string $name)
For Example, you can make action hook name "save_post", and this action can make many action callback
use WinkelCo\LaravelExtension\Facades\Hook;
use App\Models\Post;
Hook::addAction('extension_name', 'save_post', function ($title) {
$create = Post::create([ 'title' => $title ]);
}, 15);
Hook::addAction('another_extension', 'save_post', function ($title) {
Log::create("Creating post with title {$title}");
}, 10);
And You Can Run :
use WinkelCo\LaravelExtension\Facades\Hook;
$title = "Example Post";
Hook::runAction('save_post', $title);
Filter
Filter make data can modification by multiple closure, this a helpfull for make Extension. Make Filter :
Hook::addFilter(string $extension, string $name, \Closure $callback, int $priority = 10)
Apply Action :
$result = Hook::applyFilter(string $name, $value, ...$params)
For example, i make 2 function for modification a data $title
:
use WinkelCo\LaravelExtension\Facades\Hook;
Hook::addFilter('extension_name', 'save_post_params', function ($title) {
return "a {$title}.";
}, 15);
Hook::addFilter('another_extension', 'save_post_params', function ($title) {
return strtolower($title);
}, 10);
$title = "Example Post";
$result = Hook::applyFilter('save_post_params', $title);
// result output : a example post.
Menu Builder
This package include a simple menu builder, for make dynamic menu in your project,
this is a example :
use WinkelCo\LaravelExtension\Facades\Menu;
Menu::add('admin.navbar', 'Dashboard', url('/'));
Menu::add('admin.navbar', 'Extension', url('/extension'));
And then, for render to string html, use this. For example i am make sidebar.blade.php
:
@php
$menu = Menu::render('admin.navbar', function ($title, $url) {
return '<li class="nav-item">
<a class="nav-link" href="'.$url.'">
<i class="nav-icon la la-lg la-dashboard"></i>
'.$title.'
</a>
</li>';
});
@endphp
<div class="sidebar">
<nav class="sidebar-nav">
<ul class="nav">
{!! $menu !!}
</ul>
</nav>
</div>
Unit Test
You can running test with phpunit with this command :
composer test
or : (installed phpunit via composer)
vendor/bin/phpunit tests/HookActionTest
vendor/bin/phpunit tests/HookFilterTest
vendor/bin/phpunit tests/MenuBuilderTest
Examples
Making Dynamic css and javascript in html blade
For example, a make a page with dynamic component with Hook filter.
In layouts/app.blade.php
:
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Example Page</title>
@applyfilter("html__styless")
<!-- dynamic styles with Hook Filter -->
@applyfilter
</head>
<body class="app aside-menu-fixed sidebar-lg-show">
<div id="app"></div>
@applyfilter("html__scripts")
<!-- dynamic scripts with Hook Filter -->
@applyfilter
</body>
</html>
And in controlle :
public function index()
{
// system filter
Hook::addFilter("system", "html__styles", function ($old_value) {
return $old_value . '<link href="bootstrap.min.css" rel="stylesheet">';
}, 15);
Hook::addFilter("system", "html__scripts", function ($old_value) {
return $old_value .'<script src="bootstrap.min.js"><script>';
}, 15);
// another extension filter
Hook::addFilter("example_extension", "html__scripts", function ($old_value) {
return '<script src="jquery.min.js"><script>' . $old_value;
}, 15);
return view('layouts.app');
}
And then, final result html is :
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Example Page</title>
<!-- dynamic styles with Hook Filter -->
<link href="bootstrap.min.css" rel="stylesheet">
</head>
<body class="app aside-menu-fixed sidebar-lg-show">
<div id="app"></div>
<!-- dynamic scripts with Hook Filter -->
<script src="jquery.min.js"><script>
<script src="bootstrap.min.js"><script>
</body>
</html>
License
The MIT License (MIT). Please see License File for more information.