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

Lacking full support for Closures #57

adjenks opened this issue Jan 30, 2017 · 4 comments

Lacking full support for Closures #57

adjenks opened this issue Jan 30, 2017 · 4 comments


Copy link

adjenks commented Jan 30, 2017

On the releases page it states that there was added support for closures:

However, I found that when I used a closure directly on a template variable a closure would not work.
Only when using a "repeat" tag do closures appear to work. I'm not sure where you would fix this, but I found that closure support was provided in RepeatController.php in these lines:

elseif ($source instanceof Closure) {
    $this->iterator = new ArrayIterator( (array) $source() );

So perhaps something similar needs to be done.

For example this will fail to load:
$details = function(){return 'some string';};
$template->details = $details;

<b tal:content="details"></b>

But if $details was a closure that returned an array and it was iterrated over like so it works:

 $details = function(){return [0=>['name'=>'Jim']];};

<li tal:repeat="detail details" class="media">
    <div tal:content="detail/name">Name Here</div>

There might be a typo somewhere in that code but you should get the idea.

I wanted to use a closure to lazy load my template variable but it only worked when I used repeat, so I believe I found a problem. I found that I can temporarily work around this problem by returning a one element array and using the tal:repeat directive.

Copy link

Hi! Thank you for taking the time to report this.

In regards to your statement

I found that when I used a closure directly on a template variable a closure would not work.

Could you give some more detail as to what the effect is when this is done? (i.e. is an error visible or is an exception thrown? If so, what is the error message and/or stack-trace?).

I've made two minimal test-cases based on the example you gave but both seem to work (using PHP 5.6 or PHP 7).

Could you provide a minimal test-case that does not work?

Copy link

Potherca commented Feb 1, 2017

A failing test-case and an example of his workaround have been provided by @adjenks

As he correctly states:

It appears that the issue only shows up if the returned type is an array.

I can accessfoo/nested with tal:content="foo/nested" when it is not a closure, but when it is a closure I cannot access it the same way. I can however access it if I put it in a deeper array and then use repeat.

The failing case produces the following error:

PHPTAL Exception

Array doesn't have key named 'nested'

In <string 3272f4bb7302adf9f5af11e8b36e20f5> line 6

#0 /app/vendor/phptal/phptal/classes/PHPTAL/Context.php(423): PHPTAL_Context::pathError(Array, 'nested', 'nested', NULL)
#1 /app/vendor/phptal/phptal/classes/PHPTAL.php(837) : eval()'d code(19): PHPTAL_Context::path(Array, 'nested')
#2 /app/vendor/phptal/phptal/classes/PHPTAL.php(667): tpl_00000000_string_3272f4bb7302a__ZPddJbn1I4g1iAxcpA1O6w(Object(PHPTAL), Object(PHPTAL_Context))
#3 /app/web/case-04-array-indirect-assignment.php(34): PHPTAL->execute()
#4 {main}

Copy link

adjenks commented Mar 3, 2017

@Potherca Thanks for working on the bug report. How goes the battle?

Copy link

Hi @adjenks,

currently a lot of of my (spare) time is absorbed by other projects.
My current time-frame would allow me to look into fixing this issue early April.

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

No branches or pull requests

2 participants