cethyworks/content-injector-bundle
Installation:
composer require cethyworks/content-injector-bundle
Register the bundle in AppKernel.php (or config/bundles.php for Symfony 4+):
new Cethyworks\ContentInjectorBundle\CethyworksContentInjectorBundle(),
First Injection: Inject a simple string into all responses:
$subscriber = $container->get('cethyworks_content_injector.subscriber');
$subscriber->registerCommand(function() { return '<script>console.log("Hello!");</script>'; });
Verify: Check the rendered page source to confirm the injected content appears.
Inject a footer script dynamically:
$subscriber->registerCommand(function() {
return '<script src="/dynamic-footer.js?v=' . time() . '"></script>';
});
Trigger: Visit any route—script appears in the response.
Register Commands:
registerCommand(callable) for static content.Request or Response via dependency injection.
$subscriber->registerCommand(function($request) {
return $request->get('debug') ? '<!-- DEBUG MODE -->' : '';
});
TwigCommandHandler for dynamic templates.
$handler = $container->get('cethyworks_content_injector.twig_command_handler');
$handler->registerCommand('@App/Resources/views/inject/footer.html.twig', ['user' => $user]);
Form Integration:
Extend FormType to inject form-specific content:
$builder->add('field', TextType::class, [
'injector' => [
'command' => function($formView) {
return '<div class="form-hint">' . $formView->children['field']->vars['label'] . '</div>';
}
]
]);
Conditional Injection: Filter commands by route, HTTP method, or user role:
$subscriber->registerCommand(function($request) {
return $request->get('_route') === 'dashboard' ? '<div class="dashboard-only">...</div>' : '';
});
kernel.response to inspect/modify injected content:
$dispatcher->addListener('kernel.response', function($event) {
$response = $event->getResponse();
if ($response->headers->contains('X-Injected')) {
// Custom logic for injected responses
}
});
AssetMapper for versioned injected assets:
$subscriber->registerCommand(function() {
return $this->get('asset_mapper')->getUrl('js/injector.js');
});
$handler->registerCommand('@App/Resources/views/cacheable.html.twig', [], ['cache_key' => 'footer_v1']);
Event Timing:
HttpCache).kernel.response fires too early by logging $event->getResponse()->getContent().Twig Autoloading:
Resources/views directory or configure custom paths in twig.form.templates (Symfony 3) or twig.path (Symfony 4+).TemplateNotFoundException → Verify template paths and bundle compilation.FormType Extension:
injector option only works with FormType (not CollectionType or FormInterface directly). Use FormEvents::PRE_SET_DATA to attach to nested forms:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function($event) {
$event->getForm()->add('sub_form', SubFormType::class, ['injector' => [...]]);
});
Command Order:
$subscriber->registerCommand(function() { return '<head>'; });
$subscriber->registerCommand(function() { return '<body>'; }, 10); // Lower priority = later execution
$subscriber = $container->get('cethyworks_content_injector.subscriber');
$subscriber->registerCommand(function() {
return '<!-- INJECTED: ' . microtime(true) . ' -->';
});
AppKernel.php to isolate issues.Custom Command Handlers:
Extend CommandHandlerInterface to support new injection types (e.g., JSON APIs):
class JsonCommandHandler implements CommandHandlerInterface {
public function handle($command, $request, $response) {
if ($response->headers->contains('Content-Type', 'application/json')) {
$response->setContent(json_encode(['injected' => $command]));
}
}
}
Register via dependency injection.
Response Modifiers:
Hook into kernel.response to transform injected content:
$dispatcher->addListener('kernel.response', function($event) {
$response = $event->getResponse();
$content = $response->getContent();
$content = preg_replace('/<!-- INJECTED_START -->(.*)<!-- INJECTED_END -->/s', '$1', $content);
$response->setContent($content);
});
Configuration:
Override default behavior via config/packages/cethyworks_content_injector.yaml:
cethyworks_content_injector:
enabled: true # Disable globally
twig:
debug: false # Disable Twig debug for injected templates
$subscriber->registerCommand(function($request) {
return $request->get('variant') === 'A' ? '<link rel="stylesheet" href="/a.css">' : '<link rel="stylesheet" href="/b.css">';
});
data-* attributes:
$subscriber->registerCommand(function() {
return '<div data-injected="footer" data-timestamp="' . time() . '">...</div>';
});
$subscriber->registerCommand(function($command) {
return $this->get('twig')->escapeFilter($command);
});
How can I help you explore Laravel packages today?