veronalabs / rabbit
A modern way of building WordPress plugins.
Requires
- php: >=7.2
- caseyamcl/configula: ^4.0
- illuminate/database: ^8.61
- illuminate/macroable: ^8.7
- laminas/laminas-diactoros: ^2.5
- laminas/laminas-escaper: ^2.7
- laminas/laminas-form: ^3.0
- laminas/laminas-i18n: ^2.11
- laminas/laminas-view: ^2.11
- league/container: ^3.3
- symfony/finder: ^5.1
- symfony/http-foundation: ^5.1
- veronalabs/logger-wp: ^1.0
Requires (Dev)
- dealerdirect/phpcodesniffer-composer-installer: ^0.7.0
- mikey179/vfsstream: ^1.6
- phpunit/phpunit: ^10.0
- symfony/var-dumper: ^5.1
- wp-coding-standards/wpcs: 3.0
README
About
Rabbit Framework is a modern framework designed to be a solid foundation for your WordPress plugins. the project is based on Backyard
Benefits
- Dependency injection container & service providers.
- template that helps you load the view easily.
- OOP Nonces wrapper & Factory methods.
- Caching helpers.
- HTTP Redirects with admin notices flashing.
- Macroable classes.
- LoggerWP
- Illuminate Database (Eloquent)
Requirements
- PHP 7.4 or higher.
- Composer
Usage
composer require veronalabs/rabbit
Plugin header fields
When creating a WordPress plugin, you are required to add header fields to your plugin's entry file. The Rabbit framework requires 1 additional field: Plugin Prefix
.
The Plugin Prefix
field is used by the framework to automatically define constants about the plugin.
/** * Plugin Name: Example plugin * Plugin URI: https://example.com * Plugin Prefix: EP * Description: Description * Author: Alessandro Tesoro * Author URI: https://example.com * Text Domain: example-plugin * Domain Path: /languages * Version: 0.1.0 */
Load Composer autoloader
Copy and paste the code below right after the header fields to load all the dependencies of your plugin, including the Rabbit framework.
if ( file_exists( dirname( __FILE__ ) . '/vendor/autoload.php' ) ) { require dirname( __FILE__ ) . '/vendor/autoload.php'; }
Create a new Application instance
Every Rabbit powered plugin must create an instance of a Rabbit Application. The application is responsible for the loading of the plugin.
Create a new application instance by using the get()
method.
$myPlugin = Application::get();
The plugin container
The framework handles a plugin through the Plugin
class. The Plugin
class is an extension of the PHP League dependency injection container. The container is responsible for the loading of configuration files, the registration & booting process of service providers and more.
Load your plugin into the application
After the instantiation of a Rabbit Application, you need to load your plugin into the application via the loadPlugin()
method.
The loadPlugin()
method takes 3 arguments, the third is optional.
-
The path to the plugin.
-
The path to plugin's entry file.
-
The name of the folder that holds the configuration files.
$myPlugin = $myPlugin->loadPlugin( DIR, FILE, 'config' );
The loadPlugin()
method returns the Plugin
container. You will then use the container to add functionalities to your plugin.
Configuration files
Configuration files provide an easy way to set options required by parts of application to work. Values can then be easily accessed by the plugin. A configuration file returns an associative array.
$myPlugin->config( 'key' );
Use the config()
method to access values. Keys use dot notation starting with the name of the configuration file. Take a look at the example below:
File: config/plugin.php
<?php $config = [ 'my_key' => 'my_value', ];
In order to access the my_key
value, you need to call the config()
method this way:
$value = $myPlugin->config( 'my_key' );
Configuration files are used by some features provided by Rabbit.
Add service providers
Service providers in Rabbit are used to add functionalities to your plugin. Providers can be loaded by using the addServiceProvider()
method of the container class.
$myPlugin->addServiceProvider( RedirectServiceProvider::class );
The activation & deactivation hook
Activation and deactivation hooks provide ways to execute actions when the plugin is activated or deactivated. If you're familiar with these hooks, you may remember they are called with the register_activation_hook
and register_deactivation_hook
functions.
In Rabbit you can register the activation and deactivation process by using the onActivation
and onDeactivation
methods of the Plugin
class. Both methods use a Closure as argument.
$myPlugin->onActivation( function() use ( $myPlugin ) { // Do something on activation here like update_option() } ); $myPlugin->onDeactivation( function() use ( $myPlugin ) { // Do something on deactivation here } );
Boot the plugin
Use the boot()
method of the Plugin
class to boot your plugin. The boot()
method uses a Closure that allows you to add more functionalities to your plugin.
When booting, the plugin boots the registered service providers on the plugins_loaded
hook.
To boot your plugin use the following snippet:
$myPlugin->boot( function( $plugin ) { // Do something when the plugins_loaded hook is fired. } );
Load plugin textdomain
If your plugin requires localization, you can use the loadPluginTextDomain
method inside the boot
method. The framework will use the information in your header fields to set the correct textdomain and languages folder path.
$myPlugin->boot( function( $plugin ) { $plugin->loadPluginTextDomain(); } );
Include files
The Rabbit framework comes with an easy way to include()
files in your WordPress plugin. Use the includes()
method of the Plugin
class to include files from a specific folder. Files are loaded alphabetically.
$myPlugin->boot( function( $plugin ) { $plugin->includes( 'includes' ); } );
The example above will automatically include *.php files from the includes
subfolder of your plugin.
Example entry file
<?php /** * Plugin Name: Rabbit example plugin * Plugin URI: https://example.com * Plugin Prefix: REP * Description: Example plugin * Author: John Doe * Author URI: https://example.me * Text Domain: example-plugin * Domain Path: /languages * Version: 0.1.0 */ namespace RabbitExamplePlugin; use Rabbit\Application; use Rabbit\Database\DatabaseServiceProvider; use Rabbit\Logger\LoggerServiceProvider; use Rabbit\Plugin; use Rabbit\Redirects\AdminNotice; use Rabbit\Templates\TemplatesServiceProvider; use Rabbit\Utils\Singleton; use Exception; use League\Container\Container; if (file_exists(dirname(__FILE__) . '/vendor/autoload.php')) { require dirname(__FILE__) . '/vendor/autoload.php'; } /** * Class RabbitExamplePlugin * @package RabbitExamplePlugin */ class RabbitExamplePlugin extends Singleton { /** * @var Container */ private $application; /** * WPSmsWooPro constructor. */ public function __construct() { $this->application = Application::get()->loadPlugin(__DIR__, __FILE__, 'config'); $this->init(); } public function init() { try { /** * Load service providers */ $this->application->addServiceProvider(RedirectServiceProvider::class); $this->application->addServiceProvider(DatabaseServiceProvider::class); $this->application->addServiceProvider(TemplatesServiceProvider::class); $this->application->addServiceProvider(LoggerServiceProvider::class); // Load your own service providers here... /** * Activation hooks */ $this->application->onActivation(function () { // Create tables or something else }); /** * Deactivation hooks */ $this->application->onDeactivation(function () { // Clear events, cache or something else }); $this->application->boot(function (Plugin $plugin) { $plugin->loadPluginTextDomain(); // load template $this->application->view('plugin-template.php', ['foo' => 'bar']); ///... }); } catch (Exception $e) { /** * Print the exception message to admin notice area */ add_action('admin_notices', function () use ($e) { AdminNotice::permanent(['type' => 'error', 'message' => $e->getMessage()]); }); /** * Log the exception to file */ add_action('init', function () use ($e) { if ($this->application->has('logger')) { $this->application->get('logger')->warning($e->getMessage()); } }); } } /** * @return Container */ public function getApplication() { return $this->application; } } /** * Returns the main instance of RabbitExamplePlugin. * @return RabbitExamplePlugin */ function RabbitExamplePlugin() { return RabbitExamplePlugin::get(); } RabbitExamplePlugin();
Example plugin
There is an example of using the Rabbit Framework in this repository
License
Distributed under the MIT License. See LICENSE
for more information.