squirrelphp/twig-php-syntax
Twig PHP Syntax is a Twig extension that adds PHP-like syntax to templates, letting PHP developers use familiar expressions and control structures while rendering with Twig. It bridges PHP habits and Twig's templating engine for simpler, more intuitive template authoring.
v2.0 is a maintenance-shaped major: the only functional change is that Twig's own === / !== support (Twig >= 3.23) replaces the package's hand-rolled operators. Everything else is a compatibility surface change — a bumped twig/twig constraint, deleted operator/extension classes, and all classes now marked sealed (@final).
composer require <package>:^2.0 will fail or force-upgrade Twig. Before installing, run composer why twig/twig and composer show twig/twig to confirm nothing else in the app (admin themes, mail builders, CMS bundles) pins twig/twig below 3.23.php artisan vendor:publish --tag=<package>-config on a scratch branch, then diff against your committed config. This is where template paths, the active extensions list, and environment-specific options live — the fastest way to see what the package expects..twig view that interpolates controller data and exercises a strict comparison, e.g. {% if status === 'active' %}. Confirm it renders through the package's engine and not Blade. That single template proves the engine is wired, the extension list is loading, and the native operators are resolving.grep -rn "=== \|addOperator\|new .*Operator\|extends .*Extension" app/ config/ tests/ for direct references to the removed classes, and for any custom operator you registered yourself to fill the same gap.Let the config own extension registration. The idiomatic setup is: enable/disable extensions in the published config array, not by calling addExtension() on the environment. v2.0 reinforces this — classes are sealed, so subclassing an extension to tweak behaviour is off the table. Need a variant? Write a new class implementing Twig's ExtensionInterface and register it in config alongside the package's.
Decorate, don't inherit. Since everything is now sealed, replace any class MyExtension extends PackageExtension with composition: inject the package class via the container, wrap it in your own extension, and bind your wrapper in a service provider. Same for any place you extended the loader, the environment factory, or a runtime.
Kill your duplicate strict-comparison operators. If you had registered a custom ===/!== (or copied the package's implementation into app code because you needed it on an older Twig), remove it now. Twig 3.23 ships them natively and a duplicate definition will either throw at boot or silently shadow the native one with different coercion behaviour.
Keep template data contracts in the controller. Nothing about v2.0 changes how data reaches templates; the durable pattern is a single view('...', $payload) with an explicitly shaped array or a small view-model/DTO, and View::share() reserved for genuinely global values (current user, feature flags). This keeps templates portable if you later swap engines.
Cache and precompile per environment. In production enable Twig's compiled-template cache and warm it during deploy (php artisan view:cache plus whatever the package exposes); in local, disable it. Because classes are sealed, you can't subclass the cache layer — configure it instead.
Test templates, not just controllers. A thin feature test per critical template ($this->get('/dashboard')->assertSee('...')) is the cheapest guard against a silent strict-comparison semantics change, and it's the only realistic way to catch a Twig minor-version difference.
class_exists() check, or a test that instantiates the operator will blow up; a string in a stale docblock won't. Grep for them before you trust a green CI run — dead config entries can be silently skipped.extends through, expect new @final violations. Treat them as the real migration list.null vs false, '1' vs 1, arrays vs objects, and DateTimeInterface comparisons. Behaviour should match, but "should" is not "verified in your app".=== sits in Twig's own precedence table; if any template mixed the old operator with and/or/not without parens, re-read it rather than assuming.storage/framework/views — clear those before debugging anything, or you'll chase line numbers in generated PHP.{{ dump() }} and Twig's verbose error pages require the debug extension enabled and app debug on; in production you get terse, generic messages. Don't conclude the package is broken because the message is unhelpful.|raw, macro output, and {% autoescape %} blocks. Any template ported across engines deserves a manual XSS pass.twig/twig ^3.23 and the current 3.x release so a future Twig minor can't break templates unnoticed again.^3.23 is fine, but you want the resolution recorded at merge time.How can I help you explore Laravel packages today?