williamug / modular
The Modular provides a modular architecture for Laravel applications, allowing you to organize your application into self-contained modules. This package is inspired by the concept of modular programming, making it easier to manage large applications.
Installs: 5
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/williamug/modular
Requires
- php: ^8.3||^8.4
- illuminate/contracts: ^11.0||^12.0
- illuminate/support: ^11.0||^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^10.0.0||^9.0.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
This package is auto-updated.
Last update: 2025-10-27 13:17:02 UTC
README
Modular
The Modular provides a modular architecture for Laravel applications, allowing you to organize your application into self-contained modules. This package is inspired by the concept of modular development, making it easier to manage large applications.
Features
- Create, enable, disable, and delete modules.
- Run migrations, seeders, and publish assets for specific modules.
- Generate controllers, models, and migrations within modules.
- Dynamic module loading and management.
- Supports both API-only and full-stack Laravel projects.
Installation
Install the package via Composer:
composer require williamug/modular
Run the installation command to set up the package:
php artisan modular:install
This will publish the configuration file and configure your frontend.
Available Commands
Creating a Module
To create a new module, use the module:create command:
php artisan module:create Expense
This will create a Expense module in the Modules directory with the following structure:
Modules/
Expense/
Providers/
Http/
Models/
Database/
routes/
resources/
hook.php
module.json
Enabling and Disabling Modules
Enable a module:
php artisan module:enable Expense
Disable a module:
php artisan module:disable Expense
Deleting a Module
Delete a module:
php artisan module:delete Expense
Running Migrations
Run migrations for a specific module:
php artisan module:migrate Expense
Seeding Data
Seed data for a specific module:
php artisan module:seed Expense
Publishing Assets
Publish assets for a specific module:
php artisan module:publish Expense
Generating Files
Generate a controller within a module:
php artisan module:controller Expense PostController
Generate a model within a module:
php artisan module:model Expense Post --migration
Generate a migration within a module:
php artisan module:migration Expense create_posts_table
Viewing Module Information
View detailed information about a module:
php artisan module:info Expense
Modular Navigation
Modules can register navigation items by adding a navigation key to their module.json. You can use advanced features like icons, groupings, and permissions:
{
"name": "Customers",
"slug": "customers",
"enabled": true,
"navigation": [
{ "label": "Customers", "url": "/customers", "icon": "fa fa-users", "group": "CRM", "permission": "view-customers" },
{ "label": "Invoices", "url": "/invoices", "icon": "fa fa-file-invoice", "group": "Accounting", "permission": "view-invoices" }
]
}
Helper Usage
In your sidebar Blade view, use the helper:
<ul> @foreach(modular_navigation() as $item) @if(!$item['permission'] || auth()->user()?->can($item['permission'])) <li> @if($item['icon'])<i class="{{ $item['icon'] }}"></i>@endif <a href="{{ $item['url'] }}">{{ $item['label'] }}</a> </li> @endif @endforeach </ul>
Grouped Navigation Example
@php $groups = []; foreach(modular_navigation() as $item) { if(!$item['permission'] || auth()->user()?->can($item['permission'])) { $groups[$item['group'] ?? 'Other'][] = $item; } } @endphp <ul> @foreach($groups as $group => $items) <li class="nav-group"> <span>{{ $group }}</span> <ul> @foreach($items as $item) <li> @if($item['icon'])<i class="{{ $item['icon'] }}"></i>@endif <a href="{{ $item['url'] }}">{{ $item['label'] }}</a> </li> @endforeach </ul> </li> @endforeach </ul>
Blade Directive Usage
Or use the Blade directive for a concise syntax:
<ul> @modularNavigation </ul>
This will automatically render grouped navigation items from all enabled modules, showing icons and respecting permissions.
Modular Content Injection
Modules can inject custom content into parent layouts or pages (e.g., settings, dashboard widgets, or any slot) by adding a settings, widgets, or content key to their module.json:
{
"name": "Customers",
"slug": "customers",
"enabled": true,
"settings": [
{ "label": "Customer Settings", "view": "Modules/customer/resources/views/settings.blade.php", "icon": "fa fa-cog", "group": "CRM", "permission": "manage-customers" }
],
"widgets": [
{ "label": "Customer Stats", "view": "Modules/customer/resources/views/widgets/stats.blade.php", "icon": "fa fa-chart-bar", "group": "CRM", "permission": "view-customers" }
],
"content": [
{ "label": "Promo Banner", "view": "Modules/customer/resources/views/banner.blade.php", "icon": "fa fa-bullhorn", "group": "Marketing", "permission": "view-banner" }
]
}
Helper Usage for Settings
In your unified settings page:
@foreach(modular_settings() as $setting) @if(!$setting['permission'] || auth()->user()?->can($setting['permission'])) @if($setting['icon'])<i class="{{ $setting['icon'] }}"></i>@endif @include($setting['view']) @endif @endforeach
Or use the Blade directive:
@modularSettings
Helper Usage for Widgets
In your dashboard:
@foreach(modular_widgets() as $widget) @if(!$widget['permission'] || auth()->user()?->can($widget['permission'])) @if($widget['icon'])<i class="{{ $widget['icon'] }}"></i>@endif @include($widget['view']) @endif @endforeach
Or use the Blade directive:
@modularWidgets
Helper Usage for Generic Content
In any parent layout or page:
@foreach(modular_content() as $content) @if(!$content['permission'] || auth()->user()?->can($content['permission'])) @if($content['icon'])<i class="{{ $content['icon'] }}"></i>@endif @include($content['view']) @endif @endforeach
Or use the Blade directive:
@modularContent
Example Module Content (banner.blade.php)
{{-- Modules/customer/resources/views/banner.blade.php --}} <div class="module-banner"> <h4>Special Promotion!</h4> <p>Get 20% off for all new customers this month.</p> </div>
Example Project
Setting Up a Expense Module
-
Create the Module:
php artisan module:make Expense
-
Add Routes: Edit
Modules/Expense/routes/web.php:<?php use Illuminate\Support\Facades\Route; Route::get('/expense', function () { return 'Welcome to the Expense module!'; });
-
Create a Controller:
php artisan module:controller Expense ExpenseController
Edit
Modules/Expense/Http/Controllers/ExpenseController.php:<?php namespace Modules\Expense\Http\Controllers; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class ExpenseController extends Controller { public function index() { return 'Expense index page'; } }
-
Add a Model:
php artisan module:model Expense Post --migration
Edit the generated migration file to define the
poststable schema. -
Run Migrations:
php artisan module:migrate Expense
-
Enable the Module:
php artisan module:enable Expense
-
Access the Module: Visit
/expensein your browser to see the Expense module in action.
API-Only Projects
For API-only projects, the package automatically skips frontend scaffolding. You can still use all the commands to manage modules and their backend logic.
Contributing
Contributions are welcome! Please submit a pull request or open an issue to discuss changes.
License
This package is open-source software licensed under the MIT license.