Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Symfony Breadcrumb Laravel Package

azri/symfony-breadcrumb

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require azri/symfony-breadcrumb
    

    Enable the bundle in config/bundles.php:

    Azri\BreadcrumbBundle\AzriBreadcrumbBundle::class => ['all' => true],
    
  2. Basic Configuration: Add minimal config in config/azri_breadcrumb.yaml:

    azri_breadcrumb: ~
    
  3. Define Breadcrumbs in Routes: Use breadcrumb options in your route definitions (e.g., config/routes.yaml):

    acme_home:
        path: /
        options:
            breadcrumb:
                label: Home
    
  4. Render in Twig: Include breadcrumbs in your template:

    {{ breadcrumbs() }}
    

First Use Case

Display a simple breadcrumb trail for a static page (e.g., /contact):

# config/routes.yaml
acme_contact:
    path: /contact
    options:
        breadcrumb:
            label: Contact
            parent_route: acme_home

Render in Twig:

{# templates/contact.html.twig #}
{{ breadcrumbs() }}

Output: Home > Contact


Implementation Patterns

Core Workflows

1. Static Breadcrumbs

  • Pattern: Define breadcrumbs directly in route annotations/YAML/XML.
  • Example:
    acme_product_show:
        path: /products/{id}
        options:
            breadcrumb:
                label: 'Product: %%name%%'
                parent_route: acme_products_list
    
  • Dynamic Labels: Use %%placeholder%% syntax for Twig/translation placeholders. Replace in controller:
    $breadcrumbProvider->getBreadcrumbByRoute('acme_product_show')
        ->setLabelParams(['name' => $product->getName()]);
    

2. Dynamic Breadcrumbs

  • Pattern: Build breadcrumbs programmatically for non-routed entities (e.g., nested categories).
  • Example:
    foreach ($product->getCategories() as $category) {
        $crumb = new Breadcrumb(
            'Category: %name%',
            'acme_category_show',
            ['id' => $category->id],
            ['name' => $category->name]
        );
        $collection->addBreadcrumbBeforeCrumb($crumb, $productCrumb);
    }
    

3. Template Customization

  • Pattern: Override default templates (@AzriBreadcrumb/breadcrumbs.html.twig).
  • Steps:
    1. Create a custom template (e.g., templates/breadcrumbs_custom.html.twig).
    2. Configure in azri_breadcrumb.yaml:
      azri_breadcrumb:
          template: 'templates/breadcrumbs_custom.html.twig'
      
  • Template Variables:
    • breadcrumbs: Array of BreadcrumbInterface objects with:
      • route, routeParameters (for path()).
      • label, labelParameters (for trans()).

4. Bootstrap Integration

  • Pattern: Use the built-in Bootstrap template.
  • Steps:
    azri_breadcrumb:
        template: '@AzriBreadcrumb/breadcrumbs_bootstrap.html.twig'
    

5. Caching

  • Pattern: Leverage Symfony’s route cache for performance.
  • Action: Run php bin/console cache:warmup to pre-generate breadcrumb collections.

Integration Tips

With Symfony’s Router

  • Use path(breadcrumb.route, breadcrumb.routeParameters) in Twig to generate links.
  • Example:
    <a href="{{ path(breadcrumb.route, breadcrumb.routeParameters) }}">
        {{ breadcrumb.label|trans(breadcrumb.labelParameters) }}
    </a>
    

With Translations

  • Store labels in translation files (e.g., messages.en.yaml):
    breadcrumb:
        product: 'Product: %name%'
    
  • Reference keys in routes:
    options:
        breadcrumb:
            label: 'breadcrumb.product'
    

With Dynamic Controllers

  • Inject BreadcrumbProviderInterface to modify breadcrumbs on-the-fly:
    public function showAction(BreadcrumbProviderInterface $provider, Product $product) {
        $provider->getBreadcrumbByRoute('acme_product_show')
            ->setLabelParams(['%name%' => $product->getName()]);
    }
    

With API Platform

  • Use dynamic breadcrumbs for nested resources:
    $collection->addBreadcrumbBeforeCrumb(
        new Breadcrumb(
            'Parent: %name%',
            'api_parent_show',
            ['id' => $parent->getId()],
            ['name' => $parent->getName()]
        ),
        $currentCrumb
    );
    

Gotchas and Tips

Pitfalls

1. Double Percent Sign (%%) Escape

  • Issue: Single % in route labels (e.g., Product: %name%) triggers Symfony’s parameter injection.
  • Fix: Use %% in route config, then replace with % in Twig:
    {{ breadcrumb.label|replace({'%%': '%'})|trans(breadcrumb.labelParameters) }}
    

2. Circular References

  • Issue: Parent routes referencing children (e.g., parent_route: acme_child) breaks the tree.
  • Fix: Validate parent routes exist and are ancestors:
    if (!$provider->hasBreadcrumb('acme_child')) {
        throw new \RuntimeException('Parent breadcrumb not found');
    }
    

3. Cache Invalidation

  • Issue: Changes to route breadcrumbs require cache warmup:
    php bin/console cache:clear && php bin/console cache:warmup
    
  • Tip: Use cache:pool:clear azri_breadcrumb.cache_pool for targeted clearing.

4. Dynamic Crumbs Not Persisted

  • Issue: Programmatically added breadcrumbs (e.g., categories) are lost on cache warmup.
  • Workaround: Rebuild dynamic breadcrumbs in controllers or event subscribers.

5. Template Variable Conflicts

  • Issue: Custom templates may clash with Symfony’s breadcrumbs variable.
  • Fix: Use unique variable names (e.g., custom_breadcrumbs) or extend the base template.

Debugging Tips

Inspect Breadcrumbs

  • Dump the collection in a controller:
    $breadcrumbs = $provider->getBreadcrumbs();
    dump($breadcrumbs->toArray());
    
  • Check for missing routes or malformed labels.

Validate Route Config

  • Ensure parent_route values match existing route names (case-sensitive).
  • Use php bin/console debug:router to list all routes.

Translation Debugging

  • Verify translation keys exist in your locale files.
  • Test with raw labels first:
    options:
        breadcrumb:
            label: 'Raw Label'  # Test without translation
    

Extension Points

1. Custom Model/Collection

  • Implement BreadcrumbInterface and BreadcrumbCollectionInterface for custom logic:
    azri_breadcrumb:
        model_class: App\Model\CustomBreadcrumb
        collection_class: App\Model\CustomBreadcrumbCollection
    

2. Provider Service Override

  • Replace the default provider:
    azri_breadcrumb:
        provider_service_id: app.custom_breadcrumb_provider
    
  • Implement BreadcrumbProviderInterface:
    class CustomProvider implements BreadcrumbProviderInterface { ... }
    

3. Event Subscribers

  • Listen to kernel.request to modify breadcrumbs dynamically:
    public function onKernelRequest(GetResponseEvent $event) {
        $breadcrumbs = $event->getRequest()->get('breadcrumbs', []);
        // Modify or add breadcrumbs...
    }
    

4. Twig Extensions

  • Extend the breadcrumb() function in services.yaml:
    services:
        app.twig.breadcrumb_extension:
            class: App\Twig\BreadcrumbExtension
            tags:
                - { name: twig.extension }
    

Configuration Quirks

YAML vs. PHP Annotations

  • YAML: Use options.breadcrumb.label.
  • Annotations: Use options={"breadcrumb": {"label": "..."}}.
  • XML: Use <option key="breadcrumb">...</option>.

Default Template Overrides

  • The default template is @AzriBreadcrumb/breadcrumbs.html.twig.
  • Bootstrap template: @AzriBreadcrumb/breadcrumbs_bootstrap.html.twig.
  • Tip: Copy templates to templates/AzriBreadcrumb/ to override without vendor changes.

Parameter Precedence

  • Route parameters override setRouteParams() in controllers.
  • Label parameters override setLabelParams() but respect Twig/translation placeholders.

Performance

Cache Warmup

  • Run after deploying route changes:
    php bin
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui