druidvav/page-metadata-bundle
Installation Add the bundle via Composer:
composer require druidvav/page-metadata-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Druidvav\PageMetadataBundle\DruidvavPageMetadataBundle::class => ['all' => true],
];
Basic Configuration
Publish the default config (if needed) and adjust in config/page_metadata.php:
php bin/console druidvav:page-metadata:install
Key settings:
# config/page_metadata.yaml
default_metadata:
title: "Default Title"
description: "Default Description"
keywords: "default,keywords"
robots: "index,follow"
First Use Case: Adding Metadata to a Controller
Use the Metadata trait in a controller to inject metadata:
use Druidvav\PageMetadataBundle\Metadata\Metadata;
class HomeController extends AbstractController
{
use Metadata;
public function index(): Response
{
$this->setMetadata([
'title' => 'Home Page',
'description' => 'Welcome to our site!',
]);
return $this->render('home/index.html.twig');
}
}
Twig Integration
Verify metadata is rendered in your base template (e.g., base.html.twig):
<title>{{ page_metadata.title }}</title>
<meta name="description" content="{{ page_metadata.description }}">
Route-Based Metadata: Use the Metadata trait to set metadata per action:
public function about(): Response
{
$this->setMetadata([
'title' => 'About Us',
'description' => 'Learn about our company.',
'keywords' => 'about,team,history',
]);
return $this->render('about/index.html.twig');
}
Global Overrides: Extend the Metadata trait to modify behavior:
trait CustomMetadata
{
use Metadata;
protected function getDefaultMetadata(): array
{
return array_merge(parent::getDefaultMetadata(), [
'author' => 'Your Company',
]);
}
}
// src/EventListener/MetadataListener.php
public function onKernelController(ControllerEvent $event)
{
$controller = $event->getController();
if (is_array($controller)) {
$this->setMetadataForController($controller[0]);
}
}
{# base.html.twig #}
<title>{{ page_metadata.title | default('Default Title') }}</title>
{# child.html.twig #}
{% set page_metadata.title = 'Custom Title' %}
if ($this->isJsonRequest()) {
$this->setMetadata(['robots' => 'noindex']);
}
$this->setMetadata([
'title' => $this->translator->trans('page.title'),
]);
default_metadata is set in config/page_metadata.yaml to avoid runtime errors.{% set %} takes precedence over both.Metadata trait is properly used in controllers. Verify the bundle is enabled in bundles.php.page_metadata is passed to Twig templates. Debug with:
{{ dump(page_metadata) }}
Metadata class to support additional fields (e.g., OpenGraph tags):
// src/Metadata/CustomMetadata.php
class CustomMetadata extends Metadata
{
protected $customFields = ['og:image', 'twitter:card'];
public function setOgImage(string $url): self
{
$this->metadata['og:image'] = $url;
return $this;
}
}
title, description) are case-sensitive in Twig.setMetadata() multiple times in the same action unless merging data:
$this->setMetadata($this->getDefaultMetadata());
$this->setMetadata(array_merge($this->getMetadata(), ['title' => 'New Title']));
Metadata trait to test metadata logic:
$controller = $this->getMockBuilder(HomeController::class)
->onlyMethods(['setMetadata'])
->getMock();
$controller->setMetadata(['title' => 'Test']);
$this->assertEquals('Test', $controller->getMetadata()['title']);
How can I help you explore Laravel packages today?