rdrenth/twig-extension-bundle
A Symfony bundle that adds a collection of helpful Twig extensions, filters, functions, and tests to streamline template development. Install via Composer and register the bundle to access extra helpers for common templating tasks.
This release is additive: two new named string filters (ucfirst, lcfirst) land alongside a composer constraint bump and a cosmetic code-style pass. Nothing is removed, so an existing install can upgrade in place.
composer require <vendor>/<package>:^1.1. The "update composer requirements" entry in 1.1.0 means the floor for PHP/Laravel may have moved — run composer why-not <vendor>/<package> 1.1.0 before assuming the upgrade is blocked by your app rather than by the package's own constraints. If you are stuck on an older PHP or Laravel minor, stay on the 1.0.x line; the new filters are the only thing you lose.ucfirst / lcfirst appear after upgrading (php artisan config:clear first if the list is config-driven and cached).name field typed as jANE dOE is the classic target — pipe it through a lowercase normalizer then ucfirst for a display value, or through lcfirst when you are joining a greeting onto a proper noun ("dear " . lcfirst($title)).Treat filters as a formatting layer, not a validation layer. Apply ucfirst/lcfirst at the edge — presenters, API resources, Blade output — and keep raw input untouched in the database. This keeps the filters swappable and stops you from re-running migrations when formatting rules change.
Chain deliberately. The value of these two additions is composition: trim → lower → ucfirst for sentence-case display names, lower → ucfirst for e-mail local parts shown in admin UIs. Centralize the chain in one place (an accessor, a small Formatter/Presenter class, or a Blade component) rather than repeating it at each call site — otherwise the order drifts between screens and you get inconsistent casing.
Wrap them for testability. Call the filter through your own thin helper or enum of filter names so tests assert on intent (NameFormatter::display($input)) rather than on a package API you do not control. When the package changes again, one file moves.
Use data providers in tests. Casing filters have a wide input space — empty string, single char, all-caps, leading whitespace, unicode. A Pest/PHPUnit dataset of [input, expected] pairs is the cheapest way to pin behavior, and it documents what your app expects from the package.
Register your own filters in the same slot. Most packages of this shape expose a public registration contract; adding an app-specific filter (e.g. titleCase, initials) through the same mechanism keeps the calling convention consistent across built-in and custom filters. Do this in a dedicated service provider, not AppServiceProvider, so it stays discoverable.
Blade/directive integration: if your templates render user-supplied strings, apply the filter in the component class or view composer rather than inline in the template. Inline chains get copy-pasted and become untestable.
ucfirst and lcfirst are byte-oriented, not multibyte-safe. PHP's native functions only touch the first byte. For UTF-8 input (accented names, CJK, emoji-leading strings) you want mb_*-based equivalents — Laravel's Str::ucfirst() / Str::lcfirst() use the multibyte polyfill and are the safer default. Check which implementation this package's filters wrap before relying on them for non-ASCII data; this is the single most likely source of "works in staging, breaks for one user" bugs.ucfirst immediately followed by lcfirst is a no-op. lower → ucfirst gives Hello; ucfirst → lower gives hello. Write the chain once and never inline it.lcfirst on acronyms and brand names. lcfirst('NASA') → nASA. If the field can contain proper nouns or codes, guard the filter behind a check rather than applying it blanket-style.composer update --dry-run <vendor>/<package> and read the constraint diff. Laravel major/PHP minor floors are the usual culprit.bootstrap/cache/config.php) will hide the two new names and you will conclude the upgrade did not apply. php artisan config:clear && php artisan cache:clear.ucfirst/lcfirst may shadow or be shadowed by existing global helpers, Blade directives, or filters registered by other packages. If a filter resolves to the wrong implementation, dump the registry contents at boot to see who registered last — registration order usually wins.How can I help you explore Laravel packages today?