Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add strict_properties, array_methods options #3913

Open
wants to merge 4 commits into
base: 3.x
Choose a base branch
from

Conversation

danog
Copy link

@danog danog commented Nov 22, 2023

  • strict_properties: if true, treats property accesses in templates only as property accesses, without ever trying to invoke methods with the same name if the property does not exist (defaults to false).
  • array_methods: if true, treats method calls on callable array elements as if they were object method calls.

Both rules came in extremely handy @ nicelocal, as the first one increases strictness, also avoiding issues in our automated migration from smarty to twig, while the second one allows the usage of some specific abstractions.

Copy link
Member

@stof stof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of this strict_properties option.
The only way for a package to use Twig while being compatible with any project would then be to never rely on the implicit getter behavior, which would be a major breakage for the ecosystem (for instance, many things in Symfony are implemented as getters, not as public properties, as this allows computing things on-demand).
I don't think it is a good idea to force all shared packages to write non-idiomatic Twig code.

return $object[$arrayItem];
if ($type === 'method') {
if (is_callable($object[$arrayItem])) {
return $object[$arrayItem](...$arguments);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not properly integrated with the sandbox system.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

return false;
}

if ($ignoreStrictCheck || !$env->isStrictVariables()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a check on strict variables here ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This avoids falling through to the method call logic below, without throwing an exception (for consistency with the chosen strict_variables setting).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The strict_variables setting has a well-defined semantic: deciding whether undefined values are returned as null or throwing an exception.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic aims precisely at maintaining this behavior, regardless of the value of strict_properties.

@danog
Copy link
Author

danog commented Nov 22, 2023

Hi @stof,

The only way for a package to use Twig while being compatible with any project would then be to never rely on the implicit getter behavior, which would be a major breakage for the ecosystem (for instance, many things in Symfony are implemented as getters, not as public properties, as this allows computing things on-demand).
I don't think it is a good idea to force all shared packages to write non-idiomatic Twig code.

@ work we have a very large amount of twig templates, but we don't actually use any libraries from the symfony ecosystem (apart from twig), thus the fallback-to-methodcall behavior for properties was causing us issues, without any valid reasons to keep it enabled.

strict_properties is set to false by default, thus this does not affect the default behavior for anyone.

@stof
Copy link
Member

stof commented Nov 22, 2023

@danog the issue is that a shared package cannot assume that the current config is the default config. It must work in all modes. Otherwise, we create a split ecosystem.

@danog
Copy link
Author

danog commented Nov 23, 2023

@stof I now understand your point, however twig is not used exclusively with Symfony libraries: it is a standalone templating engine, that can be used even without symfony libraries; I see no real reason to offer an option to disable a behavior that, while idiomatic for twig templates in the context of Symfony, is not mandatory in contexts outside of Symfony (and in our specific case the default behavior is actually harmful, since it causes breakage and potentially unwanted behavior for thousands of templates).

A (subjective) argument can even be made that the default behavior brings actually more harm than good, as it introduces unexpected side effects for what should be just a simple property fetch, and this opinion is shared by my peers and CTO @ work.

Regardless, this PR does not aim to remove this behavior altogether, but rather provide an option to increase strictness, which frankly can only do good :)

I've added some additional docs to clarify that strict_properties should not be used in conjunction with Symfony libraries.

@stof
Copy link
Member

stof commented Nov 23, 2023

@danog being a standalone library makes its ecosystem event larger than the Symfony ecosystem, which only means that splitting the ecosystem between packages compatible with strict_properties or not compatible with it is even worse. It is not limited to the Symfony ecosystem.

Introducing this option in Twig means introducing the splitting of the ecosystem, which has a huge cost for the Twig community.

@danog
Copy link
Author

danog commented Nov 23, 2023

@stof The same argument of an ecosystem split can be made for strict_variables, autoescape with html, js values, yet these options exist and can be enabled or disabled at will; especially the html/js autoescape strategies, which were added at a later time in Twig 1.8, not directly at release, just like the proposed strict_properties.

@danog
Copy link
Author

danog commented Nov 23, 2023

Could I also get a second opinion from @fabpot as well? I strongly feel that the strict_properties option is an overall useful addition to Twig :)

@stof
Copy link
Member

stof commented Nov 23, 2023

@danog For strict_variables, the best practice is anyway to deal properly with the structure of your variables (making you compatible with strict_variables being turned on). Writing code compatible with strict_variables won't be non-idiomatic Twig.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants