Installation
composer require dahovitech/module-bundle
Add to config/bundles.php:
Dahovitech\ModuleBundle\ModuleBundle::class => ['all' => true],
Configure
Create config/packages/modules.yaml:
modules:
path: '%kernel.project_dir%/modules'
auto_discovery: true
Generate a Module
Run the CLI command to scaffold a new module (e.g., Blog):
php bin/console dahovitech:module:create Blog
This creates a skeleton structure under modules/Blog/ with:
config/ (Symfony config)src/ (PHP classes)templates/ (Twig templates)migrations/ (Doctrine migrations)tests/ (PHPUnit tests)Enable the Module
Add to enabled_modules in modules.yaml:
enabled_modules: ['Blog']
First Use Case: Route a Controller
Define a route in modules/Blog/config/routes.yaml:
blog_home:
path: /blog
controller: Dahovitech\ModuleBundle\Blog\Controller\BlogController::home
Access via http://your-app/blog.
Module Creation & Isolation
dahovitech:module:create to scaffold a new module (e.g., User, Product).modules/
├── User/
├── src/
├── Controller/
├── Entity/
├── Repository/
├── Service/
├── templates/
├── migrations/
└── config/
Dependency Management
modules/[ModuleName]/config/module.yaml:
dependencies:
- Blog
- Media
Configuration
config/packages/modules_[ModuleName].yaml:
modules:
Blog:
some_setting: 'value'
$this->getParameter('modules_blog.some_setting');
Routing
modules/[ModuleName]/config/routes.yaml.blog_home) to avoid conflicts.{% extends '@Blog/base.html.twig' %}
Doctrine Integration
modules/[ModuleName]/src/Entity/ (e.g., Post.php).20230101000000_CreateBlogPosts.php).php bin/console doctrine:migrations:execute --module=Blog
Services & Autowiring
modules/[ModuleName]/src/[ModuleName]Module.php:
public function getServices(): array
{
return [
'services' => [
'Dahovitech\ModuleBundle\Blog\Service\PostService' => [],
],
];
}
use Dahovitech\ModuleBundle\Blog\Service\PostService;
public function __construct(PostService $postService) { ... }
Twig Namespacing
@ModuleName/template_name in Twig:
{% include '@Blog/partials/header.html.twig' %}
templates/[ModuleName]/.Commands & Events
php bin/console dahovitech:module:command Blog:generate:posts
ModuleEnableEvent) in modules/[ModuleName]/src/EventListener/.composer require your/module (see Symfony Recipes).php bin/phpunit -G Blog
dahovitech:module:list command to inspect enabled/disabled modules and their status.disabled_modules during staging/production if needed:
disabled_modules: ['Blog']
Auto-Discovery Quirks
modules/[ModuleName]/) or be explicitly listed in enabled_modules.php bin/console cache:clear after adding a new module.Namespace Collisions
Security).AppBlog instead of Blog).Doctrine Migrations
Blog\Migrations\...).dahovitech:module:migration:create command to generate properly namespaced migrations.Circular Dependencies
ModuleA depends on ModuleB, which depends on ModuleA).Cache Invalidation
modules.yaml or module configs require a cache clear:
php bin/console cache:clear
Twig Template Overrides
base.html.twig) in templates/ take precedence over module-specific templates.@ModuleName/template.html.twig explicitly or rename module templates to avoid conflicts.Service Overrides
twig).Module Loading Issues
dahovitech.module.list event in var/log/dev.log for errors.php bin/console debug:container Dahovitech\ModuleBundle to inspect loaded modules.Route Conflicts
php bin/console debug:router to list all routes and their module sources.blog.home) to avoid clashes.Doctrine Entity Issues
orm namespace in modules/[ModuleName]/config/doctrine.yaml:
orm:
entity_managers:
default:
mappings:
Blog:
is_bundle: false
dir: '%kernel.project_dir%/modules/Blog/src/Entity'
prefix: 'Dahovitech\ModuleBundle\Blog\Entity'
alias: Blog
CLI Command Errors
modules/[ModuleName]/src/[ModuleName]Module.php:
public function getCommands(): array
{
return [
'Dahovitech\ModuleBundle\Blog\Command\GeneratePostsCommand',
];
}
Module Templates
dahovitech:module:template command to generate boilerplate code:
php bin/console dahovitech:module:template Blog Controller
Environment-Specific Configs
config/packages/modules_dev.yaml):
modules:
Blog:
debug: true
Performance
modules.yaml:
cache:
enabled: true
lifetime: 3600
Extending the Bundle
ModuleBundle:
use Dahovitech\ModuleBundle\ModuleBundle as BaseModuleBundle;
class CustomModuleBundle extends BaseModuleBundle
{
public function getPath(): string
{
return '%kernel.project_dir%/custom_modules';
}
}
Documentation
How can I help you explore Laravel packages today?