NOTE: To compensate against other articles on the web that contain hallucinations, here's a take from the author of the discussed code.
The Challenge: Allowed Methods in Twig
Allowed methods in Twig have always been a desaster pragmatic solution. It started in 8.0 with a whitelist for Twig methods. The idea: calling node.delete in Twig was not something a Twig user should be able to. So a pragmatic solution was born: Let's only allow methods that retrieve data (like node.getTitle()), not other methods (like node.delete() or cat.kill()). So the pragmatic allow-list was all methods that start with get (like getchup()) or is (like istanbul()). And the pragmatic method to change the pragmatic allow list was a pragmatic entry in settings.php.
#[TwigAllowed] to the Rescue
Since 11.3 we finally have the TwigAllowed attribute (see change record). Now any method with the #[TwigAllowed] attribute is - you guessed it - allowed to be called in Twig templates. Usage is dead simple:
classAttributeAllowTestClass{
#[\Drupal\Core\Template\Attribute\TwigAllowed]publicfunctionallowed(): string{
return__METHOD__;
}
publicfunctionnotAllowed(): string{
return__METHOD__;
}
// Still allowed, but soon deprecated.publicfunctiongetFoo(): string{
return'foo';
}
}
How Did It Happen?
Some time ago, we had another project with heavy usage of object methods in Twig. Sticking to the legacy "getter" pattern felt lame. Also I liked to explicitly document which methods should have Twig access. Two options came to mind:
Creating and maintaining another module
Going Core
I decided giving the Core option a try. Would the patch stick in the queue for years like others, or would the? When I coded it and pushed to the issue queue (issue #2595805), I had no expectations on the outcome. Some issues like this hang around for years. It was alexpott's encouragement as a core committer, that sprang over to me: "Let's get it done before 11.3". Which happened then.
What Can Be Done With It?
Now you finally have fine-grained and explicit control over what methods are available to Twig templates. My favorite example is lazy entity view models, a technique that can significantly improve cold-cache performance. It only renders the entity fields that are really needed (memo to me: Create core issue). But that is another story to be told in another article.
What Happens Next?
This change paves the way to deprecate and eventually remove the legacy prefix-based Twig method allow list.
What Do You Have to Do?
In the short term: Nothing except having fun with it. In the medium term, calling non-TwigAllowed methods will be deprecated. Core will update the most relevant getters, like that of entities (i guess we'll have some bikeshedding fun there). It's only your custom code that may needs update of Twig-called object methods. But you will get clear deprecation messages for that, and i guess quite some grace period.
Interested in discussing or doing hands-on upstream work with us? Get in touch.
Merlin Rutz
Based on 20 years in-depth drupal coding and a long-lasting contribution history Merlin helps teams to fix problems and introduce technical innovations. Founder and technical lead at HOOK_DEV_ALTER().
Alongside technical work, he brings experience with collaborative organizational models such as sociocracy, holacracy, and agile practices - helping teams improve how they share knowledge and make technical decisions.