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

jasonroman/twig-extension-bundle

A Symfony bundle that integrates custom Twig extensions into your templating layer, making it easy to register and use additional filters, functions, and tags while keeping extension configuration centralized.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony2-era bundle that packages a set of Twig extensions (filters/functions/tests) as a drop-in service bundle. Treat it as a catalog of Twig helpers, not as a framework — the entire value is the list of extensions it registers.

Minimal setup:

composer require jasonroman/twig-extension-bundle

Register the bundle in app/AppKernel.php (Symfony 2.x style — there is no Flex recipe for this):

public function registerBundles()
{
    $bundles = [
        // ...
        new JasonRoman\TwigExtensionBundle\JasonRomanTwigExtensionBundle(),
    ];
    return $bundles;
}

Where to look first: open the bundle's Resources/config/services.xml (or services.yml) and the Twig/Extension/ directory. That service definition is what wires each extension into Twig via the twig.extension tag; the extension classes are what tell you the actual filter/function/test names and signatures. Read getFilters(), getFunctions(), and getTests() in each class — those return arrays are the public API you will use day to day, and there is no other documentation worth trusting.

You can also enumerate what actually got registered without reading code:

php app/console twig:debug          # Symfony 2.5+
php app/console debug:twig          # Symfony 2.7+

First use case: pick the single helper you need in a template — typically a text-formatting filter (truncation, slug generation, word wrapping, highlighting) or a small utility function — and use it in one template before rolling it out:

{# verify the exact filter name with twig:debug first #}
<p>{{ article.excerpt|truncate(120) }}</p>

If the filter appears in twig:debug output and renders correctly, the wiring is done; everything else is just applying the same pattern.

Implementation Patterns

Use extensions in templates, not in PHP. The bundle's whole point is keeping presentation logic out of controllers. If you find yourself calling $twig->getFilter('truncate') from a service, you're using it wrong — pass raw data to the template and format there.

Discover-then-adopt workflow. For each template you touch, run twig:debug, scan the filter/function list this bundle contributes, and replace hand-rolled Twig macros or controller-side string manipulation with the bundle's helper. This is the highest-leverage day-to-day activity with a package like this: it exists to delete code you'd otherwise write three times.

Compose with the official twig/extensions package. This bundle is a supplement, not a replacement. Keep twig/extensions installed for the standard text/intl/array helpers and let this bundle cover whatever it adds on top. Both register through the same twig.extension tag, so they coexist without configuration.

Extend rather than modify. When you need a variant of a provided filter (different default length, different escaping), subclass the extension class in your own bundle and register only your subclass, or add a new Twig_SimpleFilter alongside it:

// src/AppBundle/Twig/AppExtension.php
class AppExtension extends \Twig_Extension
{
    public function getFilters()
    {
        return [
            new \Twig_SimpleFilter('short', [$this, 'short'], ['is_safe' => ['html']]),
        ];
    }

    public function short($value, $len = 80) { /* ... */ }
    public function getName() { return 'app_extension'; }
}
<service id="app.twig.extension" class="AppBundle\Twig\AppExtension">
    <tag name="twig.extension" />
</service>

Override a single filter without forking. If a provided helper's behavior is almost-but-not-quite right, define a service with the same filter name registered after this bundle's service, or (cleaner) leave the bundle's filter alone and add a distinctly named one. Twig's last-registered-wins behavior makes silent shadowing a real risk, so prefer a new name.

Template-level integration tips.

  • Prefer filters over functions when the input is a single value: {{ value|helper }} reads better and chains.
  • Wrap helpers that emit markup with {% autoescape false %} only at the narrowest scope, or verify the filter declares is_safe.
  • Extract repeated filter chains into a macro file if a helper combination shows up in more than a couple of templates.

Testing. Twig-level behavior is cheap to pin down with a unit test that renders a template string through the Twig environment with only this bundle's extension loaded — no kernel boot required. Do this once per filter you adopt; it protects you if the bundle is ever replaced.

Gotchas and Tips

This is effectively unmaintained. Zero stars, zero dependents, and a Symfony2 target mean no upstream fixes, no Symfony 4+/Twig 3 support, and no security response. Do not build a long-lived dependency on it. Practical stance: vendor the extension classes into your own bundle (copy Twig/Extension/*, keep the MIT license header), register them yourself, and drop the Composer requirement. You get the same helpers with zero supply-chain risk and can modernize the Twig_Extension API yourself.

Twig 1.x API, not Twig 2/3. The classes almost certainly extend \Twig_Extension, implement getName(), and use \Twig_SimpleFilter/\Twig_SimpleFunction. On Twig 2–3 these classes are aliased but getName() is deprecated and removed in Twig 3 — you'll need AbstractExtension, TwigFilter, and TwigFunction. Plan for a mechanical rewrite if you vendor it.

The twig.extension tag is mandatory. A service registered as a plain service does nothing. If twig:debug doesn't show the filter, the tag is missing — not the class, not the bundle registration. This is the single most common failure mode with Twig bundles.

Clear the cache after service changes. Symfony's compiled container caches the tagged-service map. After editing services.xml or overriding a definition, php app/console cache:clear --env=dev (and prod if you're debugging there). "My filter stopped existing" is nearly always a stale container.

Autoescaping surprises. A filter that returns HTML (highlighting, markup generation) will be escaped unless it declares is_safe => ['html']. Check the getFilters() options array before wondering why tags appear as text. Conversely, don't add |raw to work around it — fix the safety declaration.

Name collisions are silent. If another bundle registers the same filter name, you get whichever wins the registration order — no error, no warning. Run twig:debug and note which filters are contributed by this bundle so you can recognize a collision later.

Debugging checklist, in order: (1) is the bundle in AppKernel? (2) is the service tagged twig.extension? (3) does twig:debug list it? (4) is the cache cleared? (5) is escaping eating the output? Ninety percent of issues stop at step 3.

Extension points worth knowing. The bundle is small enough that the "extension points" are just PHP: subclass an extension class, decorate the service, or add your own extension alongside it. There is no configuration tree to speak of — don't go looking for a config.yml section, because a bundle of this size typically has none.

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.
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
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console