Tracks implementation of missing PHP Twig features relative to the parity table in README.md. Phases group independent items that can be worked on in parallel.
No parser work required. Each filter is independent and follows the existing filter pattern.
-
findfilter (3.11+) — first element matching an arrow function predicate; effectivelyfilterreturning only the first result -
shufflefilter (3.11+) — randomize array order -
invokefilter (3.19+) — call an arrow function value as a filter (e.g.{{ fn|invoke(arg) }}) -
data_urifilter — encode content as a base64data:URI; optionally accept a MIME type argument -
slugfilter (3.3+) — URL-safe slug; decide on Unicode normalization strategy (e.g.slugify, nativeIntl, or regex-based)
Each is an independent parser + node + executor addition. Light touch — no existing behaviour changes.
-
===/!==strict equality (3.23+) — reuse the comparison logic from thesame astest -
xorlogical operator (3.15+) — logical exclusive OR; bitwiseb-xoralready exists as a template -
?.null-safe attribute access (3.23+) — returnnullinstead of throwing when the left-hand side isnull
Each test is a standalone addition with no parser changes.
-
sequencetest — is an indexed (non-associative) array -
mappingtest — is an associative array / object -
instanceoftest (3.15+) — checks class inheritance; note sandbox implications
Requires non-trivial parser changes. Destructuring variants share infrastructure and are best tackled together.
-
=assignment expression (3.23+) — assign within expression context ({% do x = 1 %},{{ result = fn() }}, chaineda = b = v) - Sequence destructuring (3.23+) —
{% do [a, b] = arr %}with skip slots and null padding for short arrays - Object destructuring (3.23+) —
{% do {name, email} = user %}with key-based extraction
Each tag is independent. types is simpler (no runtime effect); guard requires a feature-registry concept.
-
typestag (3.13+) — static type declarations; no runtime effect, compile-time / IDE metadata only -
guardtag (3.15+) — compile-time feature detection ({% guard filter markdown_to_html %}…{% else %}…{% endguard %})
Higher effort, external dependencies, or JS adaptation not yet scoped.
-
ufilter — returns a Unicode proxy object with ~15 methods (truncate,wordwrap,normalize,camel,snake, etc.); effectively a small string library -
enumfunction +enum_casesfunction (3.12+) — PHP enum access; JS has no native enums, so an adapter/registry approach is needed -
cachetag (3.2+) — fragment caching with TTL and tag-based invalidation; needs a cache adapter interface - Inline expression comments
# …(3.15+) — lexer change to allow{{ value # comment }} - Number literals with
_separator (3.17+) —1_000_000,3.141_592; lexer change only