Installation:
composer require atoolo/microsite-bundle
Ensure atoolo/resource-bundle, atoolo/rewrite-bundle, and atoolo/security-bundle are also installed (handled as dependencies).
Enable the Bundle:
Add to config/bundles.php:
return [
// ...
Atoolo\MicrositeBundle\AtooloMicrositeBundle::class => ['all' => true],
];
Configuration:
Define microsites in config/packages/atoolo_microsite.yaml:
atoolo_microsite:
microsites:
- path: '/blog'
bundle: 'App\Microsite\BlogBundle'
resources: ['%kernel.project_dir%/microsites/blog']
First Use Case:
Create a microsite bundle (e.g., BlogBundle) with a Resources/ directory for templates, assets, and configurations. The bundle must extend Atoolo\ResourceBundle\ResourceBundle.
Path Routing:
Use the microsite_rewriter to handle URL routing. Example in a controller:
use Atoolo\RewriteBundle\Rewrite\RewriteInterface;
public function __construct(private RewriteInterface $rewriter) {}
public function index(): Response
{
$path = $this->rewriter->rewrite('/blog/article');
return $this->renderTemplate($path);
}
Resource Isolation:
Microsites leverage atoolo/resource-bundle for isolated assets (CSS, JS, images). Example:
# config/packages/atoolo_resource.yaml
atoolo_resource:
bundles:
- { bundle: 'App\Microsite\BlogBundle', prefix: 'blog' }
Access assets via:
{{ asset('bundles/blog/css/style.css') }}
Security:
Integrate with atoolo/security-bundle for role-based access:
# config/packages/atoolo_security.yaml
atoolo_security:
microsites:
- { path: '/blog', roles: ['ROLE_BLOG_EDITOR'] }
Template Inheritance: Extend base templates from the main app while overriding microsite-specific sections:
{# templates/blog/base.html.twig #}
{% extends 'base.html.twig' %}
{% block title %}Blog - {{ parent() }}{% endblock %}
Event Listeners:
Use Atoolo\MicrositeBundle\Event\MicrositeEvent to hook into lifecycle events (e.g., pre/post-rewrite):
use Atoolo\MicrositeBundle\Event\MicrositeEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class MicrositeSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
MicrositeEvent::PRE_REWRITE => 'onPreRewrite',
];
}
public function onPreRewrite(MicrositeEvent $event): void
{
$event->setPath(strtolower($event->getPath()));
}
}
Dynamic Microsites: Load microsites dynamically via a database or API. Example:
$microsites = $this->micrositeManager->findAll();
foreach ($microsites as $site) {
$this->micrositeManager->register($site['path'], $site['bundle']);
}
Asset Versioning:
Enable versioning in atoolo/resource-bundle for cache busting:
atoolo_resource:
versioning: true
Rewrite Order:
The microsite_rewriter must run before other rewriters (e.g., Symfony’s UrlGenerator). Configure in config/packages/atoolo_rewrite.yaml:
atoolo_rewrite:
rewriters:
- { service: 'atoolo_microsite.rewriter', priority: 100 }
Trailing Slashes:
Paths must end with a slash (e.g., /blog/ vs /blog). Configure in atoolo_microsite.yaml:
atoolo_microsite:
strict_slashes: true
Bundle Autoloading:
Ensure microsite bundles are autoloaded in composer.json:
{
"autoload": {
"psr-4": {
"App\\Microsite\\": "microsites/"
}
}
}
Circular Dependencies:
Avoid circular dependencies between microsites. Use atoolo/resource-bundle to isolate assets and dependencies.
Enable Debug Mode:
Set atoolo_microsite.debug: true in config to log rewrite operations:
atoolo_microsite:
debug: true
Check Rewrite Logs:
Inspect Symfony’s profiler (/_profiler) for atoolo.rewrite events to debug path transformations.
Validate Config: Use PHPStan (level 9) to catch misconfigurations early. Example:
vendor/bin/phpstan analyse src --level=9
Custom Rewriters:
Extend Atoolo\RewriteBundle\Rewrite\AbstractRewriter to add logic:
use Atoolo\RewriteBundle\Rewrite\AbstractRewriter;
class CustomMicrositeRewriter extends AbstractRewriter
{
public function rewrite(string $path): string
{
if (str_starts_with($path, '/api/')) {
return '/internal-api' . $path;
}
return $path;
}
}
Register in services.yaml:
services:
App\Rewrite\CustomMicrositeRewriter:
tags: ['atoolo.rewriter']
Dynamic Resource Loading:
Override Atoolo\ResourceBundle\Resource\ResourceManager to load resources from external sources (e.g., S3):
use Atoolo\ResourceBundle\Resource\ResourceManagerInterface;
class S3ResourceManager implements ResourceManagerInterface
{
public function findResource(string $path): ?ResourceInterface
{
// Logic to fetch from S3
}
}
Security Overrides:
Extend Atoolo\SecurityBundle\Security\MicrositeVoter to add custom rules:
use Atoolo\SecurityBundle\Security\MicrositeVoter as BaseVoter;
class CustomMicrositeVoter extends BaseVoter
{
protected function supports(string $attribute, $subject): bool
{
return $attribute === 'MICROSITE_CUSTOM_RULE';
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
// Custom logic
}
}
Cache Rewrites:
Enable caching for the rewriter in atoolo_rewrite.yaml:
atoolo_rewrite:
cache: true
Lazy-Load Microsites:
Use Symfony’s LazyProxy to defer microsite bundle loading until first use:
use Symfony\Component\HttpKernel\LazyProxy\LazyProxyInterface;
class LazyMicrositeBundle implements LazyProxyInterface
{
public function isProxy(): bool { return true; }
public function getWrappedService(): object { /* Load bundle */ }
}
How can I help you explore Laravel packages today?