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 Extensions Bundle Laravel Package

stinger-soft/twig-extensions-bundle

A Symfony bundle from Stinger Soft that provides a collection of Twig extensions, adding handy filters, functions and tags to your templates. Drop it into your project to extend Twig's built-in capabilities and keep view logic concise.

View on GitHub
Deep Wiki
Context7

Getting Started

Know what you're installing first. This bundle is a thin Symfony registration layer — essentially a Bundle class plus a DI extension that tags the Twig extensions from stinger-soft/twig-extensions with twig.extension. There is no template DSL, no config UI, no runtime engine. The functionality you actually get lives in the sibling library, so read that package's src/ before you read this one.

If you're coming from Laravel, note the mismatch immediately: this is a Symfony bundle and will not be auto-discovered by Laravel's package discovery. You have two realistic paths:

  1. Install stinger-soft/twig-extensions directly (skip the bundle) and register the extensions with whatever Twig environment you use — typically rcrowe/twigbridge, via the extensions array in config/twigbridge.php:
    'extensions' => [
        // globally enabled
        'enabled' => [
            \StingerSoft\TwigExtensions\StringExtension::class,
            \StingerSoft\TwigExtensions\ArrayExtension::class,
        ],
        'disabled' => [],
    ],
    
  2. Or write a small ServiceProvider that binds the extension classes as singletons and calls $twig->addExtension(...) in a booted callback — the bundle gives you nothing a 20-line provider doesn't.

If you're actually on Symfony, install and register normally:

composer require stinger-soft/twig-extensions-bundle
// config/bundles.php
StingerSoft\TwigExtensionsBundle\StingerSoftTwigExtensionsBundle::class => ['all' => true],

(For pre-Flex apps, add it to AppKernel::registerBundles().)

First place to look: the bundle's DependencyInjection/ directory and Resources/config/services.*. That is the entire public surface area — it tells you exactly which classes are registered, whether they're public, whether there's a configuration tree, and whether any extension is conditional on an optional dependency being installed.

First use case to validate: a template that does string and array munging you'd otherwise do in PHP — {{ title|slugify }}, {{ list|array_unique|join(', ') }}, sorting a collection of entities by a property without writing a custom filter. If those work, the wiring is correct and everything else is just discovering the remaining filters.

Implementation Patterns

Treat the underlying library as API, the bundle as plumbing. The stable contract you code against is "a set of Twig filters/functions exists in the environment." Register them, then assert their presence in a smoke test rather than assuming.

Service-provider pattern for Laravel/TwigBridge (the common case here):

public function register(): void
{
    $this->app->singleton(StringExtension::class);
    $this->app->singleton(ArrayExtension::class);
    $this->app->singleton(SortExtension::class);
}

public function boot(): void
{
    $this->app->extend('twig', function ($twig) {
        $twig->addExtension($this->app->make(StringExtension::class));
        return $twig;
    });
}

This keeps extensions out of global config and lets you enable them per-environment (e.g. not register the var-dumper extension in production).

Composition with your own extensions. Because these are discrete classes, you can subclass one and override a single getFilters() entry to change behavior (say, a different transliteration table for slugify) without forking the whole library. That's the cleanest extension point available here.

Sorting view models in the template. The main day-to-day win with this family of extensions is deferring collection ordering to the template layer when the ordering is presentational:

{% for product in products|sortBy('price') %}

Keep this shallow — one level of sorting in the template is fine; chained multi-key sorts belong in the controller/service layer.

Testing pattern. Don't boot a kernel to test template behavior. Instantiate a raw Twig\Environment with an ArrayLoader and addExtension() the specific class under test. This is fast, and it's how you discover the real filter signatures, since documentation is thin:

$twig = new Environment(new ArrayLoader(['t' => '{{ x|someFilter }}']));
$twig->addExtension(new StringExtension());
echo $twig->render('t', ['x' => 'Hello World']);

Pin and vendor-review. With zero dependents and zero stars, treat the dependency graph as unowned. Commit composer.lock, and read a diff of the library on every update — no one else will report breakage for you.

Gotchas and Tips

Filter name collisions are the top failure mode. Twig core already ships sort, json_encode, date, upper, trim, and friends. If a StingerSoft extension declares an overlapping name, behavior depends on registration order and Twig version, and the symptom is a silent behavior change rather than an error. Before enabling all extensions, dump the filter list twice — once with, once without — and diff:

bin/console debug:twig --filter=sort      # Symfony
php artisan twig:extensions               # TwigBridge, if available

Anything that appears in both lists deserves a manual read of getFilters().

Symfony version constraints are the likeliest blocker. A bundle with no stars and no dependents may still declare symfony/framework-bundle: ^2.8|^3.0 or similar. Check composer.json before anything else; if it's stale, composer require will fail on Symfony 6/7 and the answer is "install the underlying library directly and register the extensions yourself," which costs about five minutes.

The var-dump-style extension is a production hazard. If the bundle registers it unconditionally, either gate it behind an environment check or override the service definition to a no-op. A stray {{ some_object|dump }} in a template that ships to prod leaks internals and can fatally error if symfony/var-dumper isn't installed.

Optional dependencies produce confusing failures. Extensions that reach for var-dumper, intl, or a slugify implementation typically fail at filter invocation time, not at container build time — so the environment looks healthy until one template renders. Grep the library for class_exists and function_exists to find these, and add a smoke test that renders one line per registered filter.

Private services break direct injection. If you want to inject an extension into your own service (e.g. to reuse slugify in PHP instead of Twig), the bundle may have registered it as private. Either public: true in a compiler pass or, better, instantiate the extension class yourself — most of these are stateless and cheap.

No configuration tree means no knobs. Don't hunt for a timezone/locale/format setting; if Configuration.php doesn't exist or is empty, all behavior is hardcoded and the only customization path is subclassing or decorating. Factor that into estimates before promising a client-specific format.

Forking is cheap here, and probably correct. The bundle is a handful of files. If you need a PHP 8.4 / Symfony 7 compatible version, adding a composer.json constraint bump and a services.yaml is a smaller job than negotiating with an unmaintained upstream. Vendor the fork under your own namespace and keep the Apache-2.0 headers intact.

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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource