Plugins
NixPHP includes a clean and lightweight plugin system that allows you to extend the framework with zero configuration.
Plugins can provide additional configuration, templates (views), and custom logic via a bootstrap.php
file. Once a plugin is installed via Composer, it is automatically detected and integrated.
Plugin Structure
A NixPHP plugin mimics the structure of a full app:
your-plugin/
├── app/
│ ├── config.php // Plugin-specific configuration
│ └── views/ // Plugin-specific templates
│ └── example.phtml
├── bootstrap.php // Bootstrap logic (routes, events, services, etc.)
└── composer.json
app/config.php
is merged into the global config.app/views/
is added to the view resolver.bootstrap.php
is automatically executed when the plugin is discovered.
🛠Example composer.json
Below is a minimal but complete composer.json
for a NixPHP plugin:
{
"name": "vendor/nixphp-plugin-example",
"description": "Skeleton for your first plugin when using NixPHP",
"type": "nixphp-plugin",
"license": "MIT",
"authors": [
{
"name": "Your Name",
"email": "your@mail.com"
}
],
"require": {
"php": ">=8.3",
"fkde/NixPHP": "dev-main"
},
"autoload": {
"psr-4": {
"MyPlugin\\": "app/"
}
},
"minimum-stability": "stable",
"prefer-stable": true
}
✅ Important: -
"type": "nixphp-plugin"
is required for discovery. - The namespace (e.g.MyPlugin\\
) must match your plugin classes location.
Run:
composer dump-autoload
To ensure your classes are properly registered.
Automatic Discovery
Plugins are discovered via Composer using the package "type": "nixphp-plugin"
. Once installed, NixPHP will:
- Load
bootstrap.php
- Merge
app/config.php
- Register all
app/views/
templates
No manual registration is needed.
Accessing Plugin Metadata
plugin()->getMeta('viewPaths');
plugin()->getMeta('configPaths');
plugin()->getMeta('bootstraps');
For internal use or debugging only – no need to register anything yourself.
Example Plugin: Event Listener
my-event-plugin/
├── app/
│ └── Listeners/
│ └── UserListener.php
└── bootstrap.php
namespace MyEventPlugin\Listeners;
class UserListener
{
public function onUserRegistered($user)
{
// Log registration, send welcome email, etc.
logger()->info('New user registered: ' . $user->email);
}
}
use MyEventPlugin\Listeners\UserListener;
use function NixPHP\event;
// Register the event listener
$listener = new UserListener();
event()->listen('user.registered', [$listener, 'onUserRegistered']);
// You can also use closure-based listeners
event()->listen('user.login', function($user) {
logger()->info('User logged in: ' . $user->email);
});
use function NixPHP\event;
// After successful user registration:
$user = new User(); // Your user object
event()->dispatch('user.registered', $user);
Example Plugin: Routing to a Controller
Structure:
my-hello-plugin/
├── app/
│ └── Controllers/
│ └── HelloController.php
├── bootstrap.php
└── composer.json
HelloController.php:
namespace MyHelloPlugin\Controllers;
use Psr\Http\Message\ResponseInterface;
use function NixPHP\response;
class HelloController
{
public function index(): ResponseInterface
{
return response('Hello from the plugin controller!');
}
}
bootstrap.php:
use MyHelloPlugin\Controllers\HelloController;
use function NixPHP\route;
route()->add('GET', '/plugin-hello', [HelloController::class, 'index']);
Visit: http://yourapp.local/plugin-hello
View Resolution Order
- App
app/views/
- Plugins
app/views/
Config Merge Order
- App
app/config.php
- Plugins
app/config.php
- Framework
src/config.php
Summary
- Plugins mimic the structure of the main app (
app/config.php
,app/views/
,Controllers/
) - Auto-loaded by Composer if
"type": "nixphp-plugin"
is set - Can register routes, logic, templates, config – with no extra steps
- Can be overridden by the app cleanly
plugin()
helper gives access to metadata for advanced use