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

Twig Callable Bridge Bundle Laravel Package

covex-nn/twig-callable-bridge-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation Add the package via Composer:

    composer require covex-nn/twig-callable-bridge-bundle
    

    Register the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony <4):

    Covex\TwigCallableBridgeBundle\CovexTwigCallableBridgeBundle::class => ['all' => true],
    
  2. Basic Configuration Define your callables in config/packages/covex_twig_callable_bridge.yaml:

    covex_twig_callable_bridge:
        functions:
            my_function: App\Service\MyService::customMethod
        filters:
            my_filter: App\Service\MyService::customFilter
        tests:
            my_test: App\Service\MyService::customTest
    
  3. First Use Case Use the newly exposed Twig functions in a template (templates/index.html.twig):

    {{ my_function('input') }}
    {{ 'INPUT'|my_filter }}
    {% if '123' is my_test %}Valid{% endif %}
    

Implementation Patterns

Common Workflows

  1. Reusing Business Logic Expose domain-specific PHP methods as Twig functions to avoid duplicating logic in templates:

    # config/packages/covex_twig_callable_bridge.yaml
    covex_twig_callable_bridge:
        functions:
            format_price: App\Service\PricingService::formatCurrency
    
    {{ format_price(product.price) }}
    
  2. Dynamic Callables via Services Inject services into the bundle’s compiler pass (extend CallableBridgeCompilerPass) to register callables dynamically:

    // src/DependencyInjection/CallableBridgeCompilerPass.php
    public function process(\Symfony\Component\DependencyInjection\ContainerBuilder $container)
    {
        $definition = $container->findDefinition('covex_twig_callable_bridge.compiler');
        $definition->addMethodCall('addCallable', [
            'format_date',
            [$container->getDefinition('app.date_formatter')->getClass(), 'format']
        ]);
    }
    
  3. Grouping Related Callables Use namespacing in configuration to organize callables (e.g., user.*, math.*):

    covex_twig_callable_bridge:
        functions:
            user:
                full_name: App\Service\UserService::getFullName
                is_active: App\Service\UserService::isActive
    
    {{ user.full_name(user) }}
    {% if user is user.is_active %}Active{% endif %}
    
  4. Integration with Forms/Themes Extend Twig templates in bundles by registering callables in Resources/config/services.yaml:

    services:
        Covex\TwigCallableBridgeBundle\CovexTwigCallableBridgeBundle:
            arguments:
                $callables:
                    form:
                        render_field: App\Form\Twig\Extension::renderField
    

Gotchas and Tips

Pitfalls

  1. Callable Signature Mismatches Twig passes arguments as an array ($args), but PHP callables may expect positional arguments. Use ...func_get_args() or call_user_func_array:

    // Bad: Assumes first arg is string
    public function badExample($str) { ... }
    
    // Good: Handles any args
    public function goodExample(...$args) { ... }
    
  2. Circular Dependencies Avoid registering callables that depend on Twig itself (e.g., Twig_Environment) to prevent bootstrapping issues.

  3. Configuration Overrides Later bundle configurations silently override earlier ones. Use unique keys (e.g., app.) to avoid collisions:

    covex_twig_callable_bridge:
        functions:
            app.my_function: App\Service\MyService::method
    
  4. Security Risks

    • Arbitrary Code Execution: Never expose user-controlled input as callables (e.g., {{ user_input|call }}).
    • Sensitive Data: Avoid exposing methods that return raw database records or API keys.

Debugging

  1. Missing Callables Check for typos in YAML keys or service names. Enable debug mode (APP_DEBUG=true) to see unregistered callables in Twig’s error output.

  2. Argument Errors Use {{ dump(_context) }} in Twig to inspect passed arguments and debug mismatches.

  3. Compiler Pass Issues Clear the cache (php bin/console cache:clear) after modifying CallableBridgeCompilerPass or service definitions.

Extension Points

  1. Custom Compiler Pass Extend CallableBridgeCompilerPass to add logic (e.g., auto-registering methods from a trait):

    public function process(ContainerBuilder $container)
    {
        $reflection = new \ReflectionClass('App\Service\MyService');
        foreach ($reflection->getMethods() as $method) {
            $container->getDefinition('covex_twig_callable_bridge.compiler')
                ->addMethodCall('addCallable', [$method->name, [$method->class, $method->name]]);
        }
    }
    
  2. Dynamic Registration via Event Subscribers Register callables in response to kernel events (e.g., KernelEvents::BOOT):

    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::BOOT => 'registerCallables',
        ];
    }
    
    public function registerCallables(KernelEvent $event)
    {
        $container = $event->getKernel()->getContainer();
        $container->get('covex_twig_callable_bridge.compiler')
            ->addCallable('dynamic_func', [$container->get('app.service'), 'method']);
    }
    
  3. Namespaced Callables with Proxies Use Symfony’s proxy services to lazy-load callables (e.g., for heavy services):

    services:
        app.proxied_service:
            class: App\Service\ProxiedService
            factory: ['@service_container', get]
            arguments: ['app.proxied_service.id']
    
    covex_twig_callable_bridge:
        functions:
            proxied_func: '@app.proxied_service'
    
  4. Testing Callables Mock the compiler in tests to verify registration:

    $compiler = $this->createMock(CallableBridgeCompiler::class);
    $compiler->expects($this->once())
        ->method('addCallable')
        ->with('test_func', [$mockService, 'testMethod']);
    $container->set('covex_twig_callable_bridge.compiler', $compiler);
    
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.
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
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver