Won't fix Template macro arguments can no longer access $__globals

Affected version
2.2.0 Beta 5

Xon

Well-known member
While updating an add-on for XF2.2, I discovered that a template macro's arguments can no longer access to $__globals variable where in XF2.0-XF.21 they could.

Is this an expected or intended change?

ie, this produces different outputs XF2.2 vs earlier;
XML:
<xf:macro name="example"  arg-tmp="{{ array_keys($__globals) }}">
    {{ dump($tmp) }}
</xf:macro>
 
Last edited:

Mike

XenForo developer
Staff member
TBH, I think using variables in arguments was never really an anticipated circumstance so from my perspective, it's pretty firmly in the "undefined behavior" territory. The expected use of expression syntax is mostly to cover things that aren't string values (boolean, null, array, etc) -- roughly the same thing you'd use as default arguments to a function in PHP. If you were trying to do anything more advanced, you'd do it in the body via a conditional and an <xf:set> call.

I don't currently see any compelling reason to make a change here. The example given is trivially converted to a more expected approach.

Was there a particular reason for the approach taken?
 

Xon

Well-known member
I ended up implementing a better solution (an additional template modification to inject a <xf:set>), but it was for extending forum list display in a way which worked for XF2.1 and XF2.2

My major complaint is it is a bit of an unexpected change that $__globals works in some places but not others without any warning when the syntax is allowed.
 

Mike

XenForo developer
Staff member
I've done a fair bit more investigation here, and there's actually some definite nuance to how this works internally. The short answer here is that technically some variables are safe and potentially reasonable to include in an argument default. These are essentially the globally accessible variables, which currently means anything under $xf. As an example, arg-username="{$xf.visitor.username}" should work as expected and I imagine that might exist in some places. I think any other variable access (including calling vars() in an argument default) falls into undefined behavior as it isn't really something we expect, though it's hard to entirely block.

2.2 evaluates arguments separately from executing a macro as this is needed for macro extension support, while 2.0/2.1 did this setup in the macro's closure directly. The only difference here really ends up being what's in the scope of the arguments at the time. Previously this was already affected by the variable setup process (also including the global flag) while now it runs independently of that (so $__globals isn't available and other global variables are still in scope).

At this point, I don't think we're going to change anything here as I think I'd be surprised if it affected any other instances (unless this is a trick you were using elsewhere).
 
Top