Installation:
composer require apy/breadcrumbtrail-bundle
Enable the bundle in config/bundles.php:
return [
// ...
APY\BreadcrumbTrailBundle\APYBreadcrumbTrailBundle::class => ['all' => true],
];
First Use Case: Define breadcrumbs for a controller using PHP Attributes (preferred in Symfony 5.7+):
use APY\BreadcrumbTrailBundle\Model\BreadcrumbInterface;
use APY\BreadcrumbTrailBundle\Model\BreadcrumbTrait;
#[APY\BreadcrumbTrailBundle\Model\Breadcrumb]
class ProductController extends AbstractController
{
#[APY\BreadcrumbTrailBundle\Model\Breadcrumb(['Home', 'Products'])]
public function index(): Response
{
return $this->render('product/index.html.twig');
}
}
Render in Twig:
Include the breadcrumb trail in your base template (e.g., base.html.twig):
{{ render(controller('APYBreadcrumbTrailBundle:Breadcrumb:trail')) }}
#[Breadcrumb] on controllers or methods.#[Breadcrumb(['Home', function() { return 'Dynamic Title'; }])]
@Breadcrumb (e.g., @Breadcrumb({"Home", "Products"})).BreadcrumbInterface in controllers:
use APY\BreadcrumbTrailBundle\Model\BreadcrumbInterface;
class ProductController implements BreadcrumbInterface
{
public function getBreadcrumbs(): array
{
return ['Home', 'Products'];
}
}
APYBreadcrumbTrailBundle:Breadcrumb:add in Twig:
{% do breadcrumb.add('Custom', path('some_route')) %}
#[ResetBreadcrumbTrail]:
#[ResetBreadcrumbTrail]
#[Breadcrumb(['Home'])]
public function resetTrail(): Response { ... }
#[Breadcrumb(['Home', function() use ($product) {
return 'Product: ' . $product->getName();
}])]
#[Breadcrumb(['Home', 'Products', 'Details'])]
public function show(Product $product): Response { ... }
templates/breadcrumbs.html.twig from the bundle to your project (e.g., templates/bundles/breadcrumbtrail/).{# Example: Add icons or active state #}
<nav class="breadcrumb">
{% for item in breadcrumbs %}
<a href="{{ item.link }}">{{ item.title }}</a>
{% if not loop.last %}<span class="sep">/</span>{% endif %}
{% endfor %}
</nav>
config/services.yaml:
services:
App\EventListener\BreadcrumbListener:
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
// src/EventListener/BreadcrumbListener.php
public function onKernelController(ControllerEvent $event): void
{
$breadcrumbs = $this->breadcrumbTrailService->getBreadcrumbs();
$event->getRequest()->attributes->set('breadcrumbs', $breadcrumbs);
}
{% for item in app.request.attributes.breadcrumbs %}
{{ item.title }}
{% endfor %}
@Breadcrumb in Symfony 5.7+ triggers deprecation notices.#[Breadcrumb] attributes. Run:
composer require symfony/deprecation-contracts
composer update apy/breadcrumbtrail-bundle
function() { return 'Title'; }).
Uncaught Error: Call to undefined function.#[Breadcrumb] on the __invoke() method or implement BreadcrumbInterface.use APY\BreadcrumbTrailBundle\Service\BreadcrumbTrailService;
public function debugBreadcrumbs(BreadcrumbTrailService $trail): Response
{
dump($trail->getBreadcrumbs());
return new Response();
}
$this->breadcrumbTrailService->reset();
#[Breadcrumb(['Home', function() use ($id) {
return 'Item #' . $id;
}])]
#[Breadcrumb([
'Home',
function() {
return auth()->check() ? 'Dashboard' : 'Login';
}
])]
#[Breadcrumb(['Home', $this->translator->trans('breadcrumb.products')])]
// src/Service/CustomBreadcrumbLinkGenerator.php
use APY\BreadcrumbTrailBundle\Generator\LinkGeneratorInterface;
class CustomBreadcrumbLinkGenerator implements LinkGeneratorInterface
{
public function generate(array $options): string
{
return route('custom_route', $options);
}
}
Register in services.yaml:
services:
App\Service\CustomBreadcrumbLinkGenerator:
tags:
- { name: apy_breadcrumbtrail.link_generator }
breadcrumbs.html.twig.php bin/console cache:clear
#[APY\BreadcrumbTrailBundle\Model\Breadcrumb]).use statements.#[Route] imports.use Symfony\Component\Routing\Annotation\Route;
#[ResetBreadcrumbTrail] to clear trails between requests or lazy-load breadcrumbs.#[Cache(withContext: false)]
#[Breadcrumb(['Home', 'Cached Page'])]
public function cachedPage(): Response { ... }
How can I help you explore Laravel packages today?