knplabs/twig-explorer-bundle
Symfony bundle that integrates Twig Explorer, providing a browser-based interface to browse and inspect Twig templates. Quickly view template source, inheritance, and structure to debug and better understand your views during development.
Before you type composer require, understand what you're looking at: this is a Symfony Bundle, not a Laravel package. Laravel's service provider model can't load a Symfony Bundle subclass, there's no Flex recipe, and it's archived (23 stars, 0 dependents, no security triage). If your stack is pure Blade, the answer is "skip it and read the equivalent patterns below."
If you do run Twig inside Laravel via rcrowe/twigbridge, or you're working in a Symfony app day-to-day, the minimal path is:
composer require --dev knplabs/twig-explorer-bundle "^1.0" — expect resolution failures on PHP 8.1+/Symfony 6+/Twig 3. Check with composer why-not symfony/framework-bundle before assuming it's your fault.dev: Symfony 4/5 in config/bundles.php (TwigExplorerBundle::class => ['dev' => true]), Symfony 2/3 in app/AppKernel.php.config/routes/dev/twig_explorer.yaml:
twig_explorer:
resource: "@TwigExplorerBundle/Resources/config/routing.xml"
prefix: /_twig-explorer
bin/console debug:router | grep -i twig, then hit that path.127.0.0.1 (see Gotchas).Where to look first: the filter/function list, because that's the actual value. It tells you which installed bundle provides |markdown, |trans, |slugify, |image_filter. That's the whole point.
First use case (Symfony): pull up a legacy project, search for a filter name you saw in a template, jump to the providing class. First use case (Laravel only): don't install it — run php artisan view:cache + read your Blade directives, or debug:twig if TwigBridge is present. If you want the browser experience, spend 100–200 lines building php artisan twig:inspect (or blade:inspect) that reflects over Twig\Environment::getExtensions() / your registered directives.
The explorer is a discovery tool, and every useful workflow is really "I need to know what's registered before I act." Patterns that transfer whether you're using the bundle directly or a small internal equivalent:
vendor/ for |markdown.acme/core-bundle already provides something functionally equivalent. Duplicate registrations shadow silently — Twig's last-registered-wins — so spotting an existing one is cheaper than debugging why your new filter "doesn't fire."dev only and protect the route. In Symfony:
# config/packages/security.yaml (dev)
security:
access_control:
- { path: ^/_twig-explorer, roles: ROLE_ADMIN, ips: [127.0.0.1] }
php artisan view:clear / view:cache for Blade lifecycle inspection.artisan command reflecting over Blade::getCustomDirectives() and your View::getFinder() paths.Twig\Environment::getExtensions() → getFilters(), getFunctions(), getTests() gives you exactly the same payload.php: ^7.1, symfony/framework-bundle: ^2.8|^3.0|^4.0, twig/twig: ^1|^2. On a modern Laravel app (PHP 8.1+, Symfony 6/7 console) this is a hard resolution failure, not a warning. composer why-not symfony/framework-bundle is the fastest diagnosis.getFunctions() / getFilters() return TwigFunction / TwigFilter objects with changed constructors, NodeVisitor deprecation paths changed, and Bundle::getPath() is required in Symfony 6+. A forced install will boot-fail or throw during reflection — fork and patch, don't --ignore-platform-reqs and hope.dev. This UI enumerates template paths, extension classes, filter names, and globals. That's a real information-disclosure surface if APP_ENV is misconfigured (and Laravel's APP_ENV=local on a shared staging box is a classic). Treat "archived bundle on an untrusted network" as a red flag in any security review.bin/console debug:router | grep -i twig after enabling.templates/ path is on a shared mount, in a container with an ephemeral filesystem, or while a webpack/vite watcher is triggering rebuilds. Edit in your IDE.debug:twig is the maintained substitute. bin/console debug:twig --filter=markdown and lint:twig cover the CLI-usable 80% of what the explorer does, and they ship with your Symfony install. The explorer's delta is "browse and discover across all bundles" — that's a convenience, not a capability.Twig\Environment::getExtensions() is the seam — everything the UI shows flows from there. A clean internal replacement is a single artisan command or dev-only route that reflects over extensions and renders the same list; ~150 lines, no supply chain exposure.debug:twig on Symfony, or a small Blade/Twig inspector on Laravel.How can I help you explore Laravel packages today?