PHPStan returns: ITemplate::render() invoked with 1 parameter, 0 required
- medhi
- Generous Backer | 255
What am I doing wrong, when PHPStan returns error:
Method Nette\Application\UI\ITemplate::render() invoked with 1 parameter, 0 required.
But I only follow the documentation about Components: https://doc.nette.org/…n/components#…
In other words, render()
method must contain a parameter with the
template path.
- David Grudl
- Nette Core | 8228
You're not doing anything wrong, only Phpstan is too strict on this old design.
- Marek Bartoš
- Nette Blogger | 1275
I am just adding annotation on top of every presenter, to hint which Template class will be really used. I'ts useful when you use {templateType} macro and custom Template classes to be type-safe on both sides (presenter/control and latte)
So something like this:
/**
* @property-read ExampleTemplate $template
*/
class ExamplePresenter extends \Nette\Application\UI\Presenter {}
If you use the default template instead of custom ones, then this should
work:
@property-read Nette\Bridges\ApplicationLatte\DefaultTemplate&\stdClass $template
Eventually could be used this:
class ExamplePresenter extends \Nette\Application\UI\Presenter
{
private ExampleTemplate $template;
protected function beforeRender(): void
{
parent::beforeRender();
$this->template = $this->createTemplate(ExampleTemplate::class);
}
public function renderDefault(): void
{
$this->sendTemplate($this->template);
}
}
The sendTemplate()
part is required, Nette does not know about
the private $this->template
property.
Note it's only possible, because $this->template
property in
Nette\Application\UI\Control
is private and accessed via magically
called getTemplate()
method. In case of protected or public method
would type override fail.
Last edited by Marek Bartoš (2021-05-18 11:43)
- Ages
- Member | 128
Marek Bartoš wrote:
I am just adding annotation on top of every presenter, to hint which Template class will be really used. I'ts useful when you use {templateType} macro and custom Template classes to be type-safe on both sides (presenter/control and latte)
So something like this:
/** * @property-read ExampleTemplate $template */ class ExamplePresenter extends \Nette\Application\UI\Presenter {}
If you use the default template instead of custom ones, then this should work:
@property-read Nette\Bridges\ApplicationLatte\DefaultTemplate&\stdClass $template
Eventually could be used this:
class ExamplePresenter extends \Nette\Application\UI\Presenter { private ExampleTemplate $template; protected function beforeRender(): void { parent::beforeRender(); $this->template = $this->createTemplate(ExampleTemplate::class); } public function renderDefault(): void { $this->sendTemplate($this->template); } }
The
sendTemplate()
part is required, Nette does not know about the private$this->template
property.
Note it's only possible, because$this->template
property inNette\Application\UI\Control
is private and accessed via magically calledgetTemplate()
method. In case of protected or public method would type override fail.
Well, this is the best way, I think.
- Marek Bartoš
- Nette Blogger | 1275
Ad. private ExampleTemplate $template;
– method
flashMessage()
would fail. It assigns flashes into template from
getTemplate()
method, which means an otherwise unused template is
created and flash messages are assigned to it instead of custom one. So, using
annotation is still probably the best way.