Link with captured variable and latte strict mode not working
lulco opened this issue · 6 comments
Version: 3.1.11
Bug Description
Found by efabrica-team/phpstan-latte#398
Link accepts only string as first argument, but if we use captured variable in link its type can be Latte\Runtime\Html|string|false
which is not working with latte strict types enabled and we get error Nette\Application\UI\Component::link(): Argument #1 ($destination) must be of type string, Latte\Runtime\Html given
Steps To Reproduce
Turn on latte strict types:
latte:
strictTypes: true
Use captured variable in n:href:
{capture $link}Foo:bar{/capture}
<a n:href="$link">Foo bar</a>
Expected Behavior
No error
Possible Solution
Cast input of link to string if it is not string?
Input of link must be string and casting would only hide errors. Even casting just Html would hide errors -> Html instance usually does not make sense to be an input for link.
Capture is mostly for html context so it's also correct to return Html. Maybe it could be made context-aware and always output string for non-html input.
Otherwise I would use explicit casting to string in user code.
Basically I agree, I mentioned it in original @spaze’s issue efabrica-team/phpstan-latte#398
A similar problem was reported (and fixed) in nette/latte#326, passing Html
to img src
caused troubles.
Code taken from that issue that didn't work before but not works:
{capture $test}https://nette.org{/capture}
<img src="{$test}">
It's similar enough that I'd say it would make sense for the code used in this issue to also work. What do you think?
The difference is in the n:href
and src
. The former contains PHP code and unicode strings, the latter HTML.
{capture $link}foo+bar{/capture}
<img src="{$link}"> -> <img src="foo+bar"> OK
<a n:href="$link"> -> <?php $link = 'foo+bar'; // BAD!!!
$link = 'foo+bar'; // THIS IS OK
I see, thanks. So just to make sure I understand it correctly, \Nette\Bridges\ApplicationLatte\Nodes\LinkNode
should ideally check whether $destination
is a string and not an Html object to make sure it works as intended even with $strictTypes = false
, is that correct?
Yeah. But you'd have to do a lot of checks in a lot of places. It would probably be more practical to switch to strictTypes = true
in general, or remove Html::__toString()
, or modify __toString()
to return ASCII.