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

[4.x] Antlers: Improves custom variable assignment inside tags #8818

Merged
merged 1 commit into from
Oct 9, 2023
Merged

[4.x] Antlers: Improves custom variable assignment inside tags #8818

merged 1 commit into from
Oct 9, 2023

Conversation

JohnathonKoster
Copy link
Contributor

This PR improves an over-aggressive internal tag parameter check. This internal check looks for specific tag parameters that will modify the resulting scope in some way that causes the current renderer to be unable to handle the tag's results.

With the current over-aggressive check, the following simplified example:

{{ _the_count = 1; }}

{{ collection:articles limit="3" }}
    {{ _the_count += 1; }}
    Entry: {{ _the_count }}
{{ /collection:articles }}

would produce the following output:

Entry 1
Entry 1
Entry 1

The current check is over-aggressive since it will pass if the tag contains any parameter with the same name as an existing modifier. The refactored check will only pass if the tag has any of the following parameter names:

  • as
  • scope
  • handle_prefix

The AntlersNode retains the existing hasModifierParameters method, even though internal use has been discontinued, because it's a public method and third-party code might be using it for template analysis.

For performance reasons, the AntlersNodeParser now directly conducts the new check and sets a public property on the node. This change helps avoid array lookups and additional method calls in a hot code path.

Note: this check exists to help decide if the runtime's current NodeProcessor instance can handle the tag's results instead of relying on the AntlersLoop class or parseLoop method on the tag instance. Both have severe performance implications with the runtime and reusing the node processor as much as possible is always preferred. However, things get complicated with the above list of tag parameters, where a new copy of the current scope is required to prevent unintended side effects.

The current behavior happens because the runtime cannot accurately detect/trace what is happening inside the AntlersLoop class or the parseLoop methods. A workaround for this behavior is to simply alias the results:

{{ _the_count = 1; }}

{{ collection:articles limit="3" as="oo_shiny" }}
    {{#
        This works because the runtime *can* trace the assignments across scope barriers.
        Even though the as will force a new renderer to be created, the runtime is still
        handling the iteration/looping itself, instead of the tag's parseLoop method.
    #}}
    {{ oo_shiny }}
        {{ _the_count += 1; }}
        Entry: {{ _the_count }}
    {{ /oo_shiny }}
{{ /collection:articles }}

@JohnathonKoster JohnathonKoster changed the title [4.x] Improves custom variable assignment inside tags [4.x] Antlers: Improves custom variable assignment inside tags Oct 8, 2023
@jasonvarga jasonvarga merged commit af63932 into statamic:4.x Oct 9, 2023
18 checks passed
@jasonvarga jasonvarga deleted the antlers-custom-variable-inside-tags-with-modifier-name-collisions branch October 9, 2023 18:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants