Parts
go to part...
We've just finished developing a basic Laravel 5 package. This time we'll talk about how to develop more complex packages, which include middlewares, configuration, database migrations, routes, controllers, and views. To start, implement boilerplate code of a Laravel package. Take a look at the first part of this tutorial if you need a refresher.
Now, testing something like this outside a Laravel project is not so convenient. Luckily, you can include a local composer package into a project. Let's create a new Laravel project (you can use an existing one). Then we'll reference a local package. Open the project's composer.json
and add a new section.
"repositories": {
"your-vendor/your-package": {
"type": "path",
"url": "relative/or/absolute/path/to/your/package",
"options": {
"symlink": true
}
}
}
Finally, run this in your terminal:
composer require your-vendor/your-package @dev
After that any changes you make to your package locally will be available in the Laravel project right away without the need to perform any additional actions. The only thing is, you'll have to re-run this command every time you add any new packages to your package's composer.json
require
section.
Middlewares
To add a middleware to your package, create a new folder called Middleware
inside your src
folder. Actually, this folder could be called differently, but I'll stick to the conventional name.
Create a new middleware file inside. I would just generate a blank middleware inside our Laravel project with artisan and copy the code over to our file. Don't forget to change the namespace to YourVendor\YourPackage\Middleware
.
You can develop the middleware as usual. To use the middleware in your project register it as you would normally do inside the app/Http/Kernel.php
file. For example, like this:
protected $middlewareGroups = [
'web' => [
...
\YourVendor\YourPackage\Middleware\YourMiddleware::class,
],
...
];
Database Migrations
To include database migrations into your project create a new folder database/migrations
inside the src
folder. Again, I'm just going with the familiar folder name and you are not limited here. Create the usual migration files inside the folder. Consider giving a prefix to your table names to avoid possible conflicts with the user's tables.
Now go to your package's service provider and add the boot
method. Call $this->loadMigrationsFrom()
and pass the path to the migrations directory to it. After this step your package's migrations will be run automatically when you execute php artisan migrate
in your Laravel project.
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
$this->loadMigrationsFrom(__DIR__ . '/database/migrations');
}
Models
Create any folder to store your models. I'd go with src/Model
. Create regular Laravel model files that extend Illuminate\Database\Eloquent\Model
inside the folder. The namespace would be in this case YourVendor\YourPackage\Model
.
Configuration
Same as with everything you should create a new folder to store your configuration files, for example src/config
. Create a new config file with a suitable name, for example your_package_name.php
. A configuration file is a php file which simply returns an array with values.
Now open your service provider file. Add the following code to the register
method to be able to get configuration values from inside the package.
if ($this->app->config->get('your_config_file') === null) {
$this->app->config->set('your_config_file', require __DIR__ . '/config/your_config_file.php');
}
You probably want your users to be able to publish your config files so that they could change the settings inside. To do so insert the code below into the boot
method. I talked about this method in the section about migrations.
$this->publishes([
__DIR__ . '/config/your_config_file.php' => config_path('your_config_file.php'),
]);
Routes
Create a routes file anywhere, for example src/routes.php
. Add the routes as you would normally do in a Laravel project. To tell Laravel to use these routes, add the following code to the register
method of your service provider:
$this->loadRoutesFrom(__DIR__ . '/routes.php');
Alternative approach
Don't add the line above into your service provider. Instead, create a static method called routes
inside one of your package's main classes. For example:
class YourMainClass
{
public static function routes()
{
Route::get('/my-route', function () {
return 'A route from the class!';
});
}
}
The routes won't be loaded automatically in this case. The users of your package will have to add this line to their routes file:
YourMainClass::routes();
This is less convenient but gives your users more control over the routes. Now they can add middlewares and/or prefixes to your routes by putting the line above inside a group, e.g.:
Route::middleware('auth')->prefix('admin')->group(function () {
YourMainClass::routes();
});
Controllers
Create a controller file inside any folder, for example src/Controllers/ExampleController.php
. This is going to be a simple class, we are not going to extend it from a Controller
class like the usual Laravel controllers do. Then create a method inside, for example test
and return a string from there.
<?php
namespace YourVendor\YourPackage\Controllers;
class ExampleController
{
public function test()
{
return 'Hello from the controller';
}
}
Now you can hook this method to a route inside your package. In order for Laravel to find your controller you have to specify the whole path to the class starting with a slash.
Route::get('/my-route', '\YourVendor\YourPackage\Controllers\ExampleController@test');
Views
Finally, create a folder to hold your package's views, for example src/views
. Tell Laravel where your views are located by adding this line to the boot
method of your service provider:
$this->loadViewsFrom(__DIR__ . '/views', 'yourpackage');
Now you can reference views from your package like this:
view('yourpackage::your_view');
Final Words
We've covered the main aspects of developing Laravel specific composer packages here. The process is easier than you might've thought before, it's just you need to know where to start from. Don't forget to give the proper namespaces to all of your classes depending on what aliases you specified in composer.json
and what folders the files are located in, this is important. Check Laravel's documentation for additional reference and have fun developing!
All the materials at voerro are absolutely free and are worked on in the author's spare time. If you found any of the tutorials helpful, please consider supporting the project. Thank you!