District modules
This project uses a module design pattern where functionality is split into individual modules rather than everything mashed together. This ensures a clear separation of concerns and easier packaging and extending of functionality.
The package used to facilitate this pattern is Laravel Modules. It is recommended you thoroughly read the docs as it will likely answer any questions you have about this approach.
Creating a new module
Documentation here and basic example:
lando artisan module:make my_module
Note that each District module extends the Core module which is a hard dependency.
Module generator stubs and helpers
Have a read of this page for ways to accelerate module generation, specifically stubs that suit the structure of this site. Stubs are found in stubs/nwidart-stubs and are use with the above module:make command but also module:make-**** commands (eg lando artisan module:make-model Posts PostsModule).
Adding dependencies to your module
In the module folder edit composer.json and add your dependency then cd to project root and run lando composer update, this will install all dependencies from all modules using composer-merge-plugin.
Adding config to your module
Ref. to "Config load order" readme.
- Add a config file to your module under Modules/MyModule/Config/
- Determine if you want this config to either:
- Override default app config or third party package config
- Or get overridden by the app
- Define the config file name in your module service provider (Modules/MyModule/Config/MyModuleServiceProvider) by adding to the property
$configsOverrideableor$configsOverriding
Adding middleware to your module
Each module service provider should extend Modules\Core\Providers\BaseModuleServiceProvider that takes care of populating any middleware defined by the module thanks to its own Http\Kernel.
In your module service provider you can populate arrays for each middleware type, e.g:
protected array $globalMiddleware = [Middleware\TrustProxies::class]protected array $routeMiddleware = ['can' => \Illuminate\Auth\Middleware\Authorize::class]protected array $groupMiddleware = ['web' => [Middleware\EncryptCookies::class,]]
Example
In your module dir, add Modules/MyModule/Config/myconfig.php, then in your MyModuleServiceProvider add
protected array $configsOverriding = ['myconfig'];
and finally access config with
config('myconfig');
Module dependency management
Some District Modules depend on external packages and also depend on each others. Make sure to use composer to define all of your module dependencies.
- In
MyModule/composer.jsonspecify a version, by default1.0.0 - Add external packages required by your module under
requireinMyModule/composer.jsonthen runcomposer updatefrom the project root. - Make sure to include all dependencies in
composer.json. If you are unsure, you can double check your module interdependencies at the URL/core/devtools/modules-list - Listing interdependencies in
composer.jsonwill ensure that errors are thrown if the module is removed from the repo and when runningcomposer install(part of build process) orcomposer require
Config load order
Config files are loaded in the following order:
- App (
app/config) - Third party modules
- Modules (
Modules/YourModules/Config). The order of merging then depends on how the config is defined. See here "Adding config to your module".