Weave 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 Extension Proxy Bundle Laravel Package

markup/twig-extension-proxy-bundle

Symfony bundle that adds a Twig extension proxy, routing function, filter and test calls through one service so extensions can be decorated, lazy-loaded or overridden without touching your templates.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a low-adoption (0 stars, 0 dependents) MIT-licensed bundle with no Flex recipe, so treat the README and composer.json as the source of truth before you build anything on it.

1. Install and register manually. Expect no recipe, so add the bundle yourself:

composer require markup/twig-extension-proxy-bundle
// config/bundles.php
return [
    // ...
    Markup\TwigExtensionProxyBundle\MarkupTwigExtensionProxyBundle::class => ['all' => true],
];

Class name is inferred from convention — confirm the exact FQCN in the package's *Bundle.php file after install.

2. Check version constraints first. A 0-star bundle is usually pinned to the era it was written in. Compare its composer.json requirements (twig/twig, symfony/framework-bundle) against your app before you write code against it. If it targets Twig 1.x/2.x and you're on Twig 3.x, stop there — see the redundancy note in Gotchas.

3. Where to look first, in order:

  • README.md — the intended config shape (per-extension opt-in vs. global).
  • DependencyInjection/Configuration.php — the real config keys, since docs are often stale.
  • The proxy classes themselves — they're small; you need to know exactly which Twig\Extension\AbstractExtension methods they forward.

4. First use case: a heavy extension you don't own. The value proposition is that a Twig extension with expensive constructor dependencies (a repository, an HTTP client, a paid SDK) gets instantiated on container build even when no template calls its functions. Baseline it before touching config:

bin/console debug:container --tag=twig.extension
bin/console debug:twig

Find the extension whose constructor wires a DB connection or API client, enable the proxy for that one, and re-run. If you can't demonstrate a reduction in instantiated services on a page that doesn't use the extension, the bundle is earning nothing for you.

Implementation Patterns

Measure first, adopt second. The legitimate win is narrow: extensions that are (a) registered on twig.extension, (b) never used on most requests, and (c) expensive to construct. Anything else is noise. Profile with the Symfony profiler disabled and a warm container cache — debug:twig instantiates extensions and will lie to you about laziness.

Proxy the third-party extensions you can't edit. The clean pattern is to leave the real extension registered as-is and let the bundle intercept resolution, so vendor code and its own bundle config stay untouched. Your own extensions are better fixed directly: drop the dependency into a Twig runtime instead.

Compare against Twig's native answer. On Twig 2.7+/3.x, a lazy extension is Twig\Extension\RuntimeExtensionInterface plus a runtime service, loaded by Twig\RuntimeLoader\ContainerRuntimeLoader (already wired by TwigBundle via the twig.runtime tag):

final class PriceRuntime implements RuntimeExtensionInterface
{
    public function __construct(private PriceRepository $repo) {}

    public function price(int $productId): string { /* ... */ }
}
# config/services.yaml
App\Twig\PriceRuntime:
    tags: ['twig.runtime']

If you're on Twig 3 and can edit the extension, this is the supported, zero-dependency path and the bundle is redundant. The bundle's niche is legacy stacks, or third-party bundles whose extension you can't rewrite.

Guard parity with a golden-output test. A proxy that mis-forwards metadata silently changes rendering. Assert byte-identical output with the proxy on and off:

public function testProxyParity(): void
{
    $twig = static::getContainer()->get('twig');
    $out = $twig->createTemplate('{{ my_filter("x") }}')->render([]);
    $this->assertSame('expected', $out);
}

Cover autoescaped output, functions that need the Environment, and functions that need context — those are the three places proxies break.

Roll out per-extension, one at a time. Enable on a single extension, deploy, watch error rates. A batch rollout makes a mis-forwarded is_safe or missing needs_environment impossible to bisect.

Gotchas and Tips

  • No community validation. Zero dependents means zero field-tested edge cases. Budget an afternoon to read the whole bundle source; it is small. If it's unmaintained, forking or vendoring beats waiting for a fix, especially since MIT allows it.
  • Proxy metadata drift is the main failure mode. getFunctions()/getFilters() return TwigFunction/TwigFilter objects carrying is_safe, needs_environment, needs_context, and is_variadic. If the proxy constructs these by hand and drops a flag, you get either a double-escaped output bug or an outright XSS hole. Verify flag-for-flag.
  • Tag priority changes collision resolution. Twig resolves same-named functions/filters by registration order. Proxies registering at a different twig.extension priority than the original can flip which implementation wins. If two bundles define price(), you will find out in production.
  • Laziness ≠ cheapness. A proxy that's resolved eagerly on every request simply moves the instantiation. Only extensions that go unused on a given request benefit; a homepage rendering {{ cart_count() }} gains nothing.
  • Version pinning is a real risk. Check whether the bundle supports your Symfony major. If its DI extension uses removed APIs (Symfony\Component\DependencyInjection\Definition patterns, old TreeBuilder signatures), it will fatal at container compile with an opaque error. bin/console cache:clear is the fastest reproduction.
  • Debugging recipe: disable the bundle (config/bundles.php), clear cache, render the same template, and diff output. If output changes, the proxy is the culprit — then debug:container --tag=twig.extension with and without the bundle to see what got swapped.
  • Extension point worth checking: many bundles of this shape expose an interface or abstract proxy you can extend for arbitrary services. If it exists, that's the durable way to use this package — write your own proxy against the documented contract rather than relying on the built-in ones.
  • Exit criteria: if after measurement you see no drop in instantiated services or container compile time, remove the dependency. The native twig.runtime pattern covers the same ground with no third-party surface area, and a 0-star dependency is a liability you should be able to justify to the next person who reads composer.json.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect