Last Updated:

Implementation of modular structure in Laravel

In this article, we implement modularity in Laravel. Yes, the structure of Laravel with its packages is convenient, but not always. If our project grows to gigantic proportions, it becomes more difficult to maintain the code. All the code related to a particular functionality is in different places. Controllers in the Controllers folder. Models are in the app folder, and the packs are in the views. Of course, you can create subdirectories in these directories that will separate the code by functionality. But, in my opinion, this is also not very convenient. It is much clearer when the functional code (for example, the implementation of a blog) is in the Modules/Blog directory. And all the controllers (for the blog implementation) are in the Modules/Blog/Controllers directory. And the models are respectively in Modules/Blog/Models. I'll even say more and the routers for our module will be in the Modules/Blog/Routes/routes.php file. Interesting? Then let's proceed to implementation.

 

For what it is more convenient to use modules, I described in the introduction to the article. First, we need to decide where our modules will be located. I propose (and will implement) that the modules will be located in the app/Modules directory. Each module will be located in its own directory. For example, let's implement the Test module, a task that displays the inscription "Test" (in English localization) and "Test" (in Russian localization).

Let's take a closer look at the structure of the module.

Structure of the Laravel module

As I described above, each module is in its own directory. Let's create a directory for Modules modules in the app and create a directory for the Test module – "Test" in it.

In the Test directory, let's create a directory "Controllers" in which the controllers of our module will be located.

In the Test directory, we will create the "Lang" directory, in which we will create two subdirectories "en" and "ru" (in accordance with our localizations), in which the files with translations will be located.

In the Test directory, create a directory "Migrtation", in which the migrations for the module will lie.

In the Test directory, let's create a "Model" directory for the models of our module.

In the Test directory, let's create a "Routes" directory for the files with the routes of our module.

In the Test directory, let's create the "Views" directory for the files with the packs of our module.

Now we need to create a file in which we will connect the modules to our project.

Laravel module configuration file

In the config directory (where the configuration files are stored), create a module.php file. This file will store the names of the modules that we want to load. In the same file we will store the configuration for the modules (but we will not stop there).

Listing of the module file.php

<?php return [ 'modules' => [
            'Test',
        ],
    ];

The next step is to create a Service Provider to implement a module system in Laravel.

Creating a ServiceProvider for modules in Laravel

Let's create a ModulesServiceProvider.php file in the Modules directory. Here's a listing of the file:

<?php namespace App\Modules; /** * Service provider for connecting modules */ class ModulesServiceProvider extends \Illuminate\Support\ServiceProvider { public function boot() { //get the list of modules to be loaded $modules = config("module.modules"); if($modules) { while (list(,$module) = each($modules)){ //Include the routes for the module if(file_exists(__DIR__.'/'.$module.'/Routes/routes.php') ) { $this->loadRoutesFrom(__DIR__.'/'.$module.'/Routes/routes.php');
                 }
                 //Load View
                 //view('Test::admin')
                 if(is_dir(__DIR__.'/'.$module.'/Views')) {
                     $this->loadViewsFrom(__DIR__.'/'.$module.'/Views', $module);
                 }
                 //Load the migrations
                 if(is_dir(__DIR__.'/'.$module.'/Migration')) {
                     $this->loadMigrationsFrom(__DIR__.'/'.$module.'/Migration');
                 }
                 //Load translations
                 //trans('Test::messages.welcome')
                 if(is_dir(__DIR__.'/'.$module.'/Lang')) {
                     $this->loadTranslationsFrom(__DIR__.'/'.$module.'/Lang', $module);
                 }
             }
         }
     }

     public function register()
     {

     }
 }

What is a Service Provider in Laravel you can read in the Laravel documentation. In the code itself, I left comments to explain what we are doing. Also in the comments are examples of use. Now all we have to do is connect our service provider. To do this, open the config/app file.php and add the following code:

'providers' => [
    ...
    App\Modules\ModulesServiceProvider::class,
    ...
]

You're done. Our project at Laravel has a modular system. Let's create a Test module that will display "Test" or "Test" (depending on localization) when the URL <our site>/test. In my case, it's http://modul.loc/test

Creating a module for Laravel

We have created a structure for the "Test" module. Let's create a TestController in the Controllers directory of our module.

<?php

&nbsp;

namespace App\Modules\Test\Controllers;

use App\Http\Controllers\Controller;

class TestController extends Controller

{

public function index()

{

return view('Test::index');

}

}

Working with controllers and models in the module is no different from using standard controllers and Laravel models. The main thing is to specify the correct namespace.

But the use of packs and localization files is different.

To display the bindweet, use the following view structure('<project name>::<the name of the bindwee>')

To output the translation, use trans('<Name of the module>::<translation file>.<frase for translation>')

Now let's create a binder index.blade.php in the Views directory of our module.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Test</title>
</head>
<body>
    
<h1>Наш модуль:</h1>

    {{ trans('Test::test.this_module')}}
</body>
</html>

Let's create two translation files test.php for Russian localization and English.

Листинг файла Lang/en/test.php

<?php return [ 'this_module' => 'This module',
    ];

Листинг файла Lang/ru/test.php

<?php return [ 'this_module' => 'This is a module',
    ];

It remains only to create a route. In the Routes/routes.php file, add the following code:

<?php Route::group( [ 'namespace' => 'App\Modules\Test\Controllers',
        'as' => 'test.',
    ], function(){
        Route::get('/test', ['uses' => 'TestController@index']);
    });

And finally, we need to add our module to the config/module file.php to connect the module in our project.

<?php return [ 'modules' => [
            'Test',
        ],
    ];

Check. Go to < site>/test

 

We see the output "This is a module". Because Russian localization. Let's change the localization to English. To do this, open the config/app file.php and modify:

…
'locale' => 'ru',
…

On:

…
'locale' => 'en',
…

Check.

Everything works.

And in addition to the video article:

Conclusion

We have implemented a modular system in Laravel. Now the functionality of our project can be divided into modules, and the code related to a certain functionality is in one place (module directory)