PHPStan for latte without Nette Application
- Vaielab
- Member | 5
Hello
I hope this is ok to ask a question that is only for Latte and not
for Nette.
I'm currently using the framework PHPSlim with latte following this tutorial: https://latte.nette.org/…im-framework .
I'm trying to find a way to validate with PHPStan if the template I'm using
actually exists, and if all the variables are correctly sended.
The only project I found that could do it is https://packagist.org/…hpstan-latte, but it seem to be made
for nette application framework. At least I was not able to make it work with
the tutorial, I only manage to get this error: “:-1 Latte template
home.latte was not analysed.”.
Has anyone managed to make this PHPStan extension work without nette application framework, or know a other PHPStan extension that could work for me.
Thank you
- mystik
- Member | 304
Hello
I am one of developers of that phpstan latte extension. It should be possible to adapt it for any type of application easily. It requires writing custom TemplateResolver that defines where to start collecting latte context (defined variables, render calls,… ) for analysis. It can be just few lines of code.
Can you show me how your version of presenter/control looks like?
- mystik
- Member | 304
You can define template resolver like this to match __invoke
methods in all classes extending My\Application\Action
:
namespace My\Application;
use Efabrica\PHPStanLatte\LatteContext\Resolver\LatteContextResolverInterface;
use Efabrica\PHPStanLatte\LatteTemplateResolver\AbstractClassMethodTemplateResolver;
final class SlimActionTemplateResolver extends AbstractClassMethodTemplateResolver
{
public function getSupportedClasses(): array
{
return ['My\Application\Action'];
}
protected function getClassMethodPattern(): string
{
return '/^__invoke$/';
}
}
Then add it in your phpstan.neon:
services:
- My\Application\SlimActionTemplateResolver
That should do the trick.
If your Action methods cannot be matched by common parent then it could be done too but is more complicated.
If you do not use classes at all but just functions or callbacks then it also can be done but would require fully custom TemplateResolver. I can help you with that too if it is the case.
Last edited by mystik (2023-05-04 09:27)
- Marek Bartoš
- Nette Blogger | 1246
Latte template home.latte was not analysed
@mystik This would deserve a phpstan built-in tip how to resolve the issue, e.g. with link to docs
Last edited by Marek Bartoš (2023-05-04 12:38)
- Vaielab
- Member | 5
Hello,
Thank you for the answer, I didn't think I'd have an answer from someone on
the phpstan-latte team.
Sadly, I did not managed to make the code suggested work.
I made a small repo for a very basic php slim / latte template https://github.com/…LattePhpStan
I'd really appreciate if you could take a look.
I haven't decided how I'd like to load latte in the final application, so I've try 2 ways.
The application has 3 endpoints:
/test01 ⇒ It should load the template Test01.latte, and using the
$this->engine->renderToString method directly from Latte
/test02 ⇒ It should load the template Test02.latte, and using a basic class
App\Renderer\TemplateRenderer
/test03 ⇒ Trying to use the App\Renderer\TemplateRenderer to load Test03.latte
but without the necessary variables so should return a error.
When I'm calling phpstan with ./vendor/bin/phpstan analyse –configuration phpstan.neon, I get all 3 “Latte template … was not analysed” error message.
I tried adding the TemplateResolver extends
AbstractClassMethodTemplateResolver you suggested, but it didn't change the
error message or anything.
I'm not sure where to go from here.
Thank you for your time
- mystik
- Member | 304
Problem here is that we need a way to identify controler classes. Easiest way is based on some parent or inteeface. But your controllers do not have common ancestor nor interface.
Possible solutions (from easiest to hardest):
- Define common anvestor or interface for controllers. This class/interface then should be returned from getSupportedClasses of TemplateResolver
- Alternative way is to return list of all controller classes from getSupportedClasses() but that would require manual update every time you add new Controller
- We can write more customised template resolver that would detect all conteoller classes automaticaly even without common ancestor
- Vaielab
- Member | 5
Hello,
Thank again for you help.
So I've updated the github and creating a MyController.php file and all my
controllers (test01, test02 & test03) now extends from it.
I've also updated getSupportedClasses to return
[‘App\Controllers\MyController’].
But still, I get the “Latte template … was not analysed” error
message
I've also tried to make the method index of MyController as a abstract method,
but I end up with the same problem (not currently on github)
- Lulco
- Member | 4
Hi, I'm the second contributor of phpstan-latte package. I think you News also variable collector and template path collector to be implemented. See https://github.com/…extension.md#…
- mystik
- Member | 304
Now I noticed you call render* methods directly on Engine
not
on Template
. We currently does not support that (it is not used
this way in Nette).
It would be easy fix (I will make it tommorow) but for now you can try replace
$string = $this->engine->renderToString('Test01.latte', ['items' => $items, 'title' => 'From Test01']);
by
$string = $this->engine->createTemplate()->renderToString('Test01.latte', ['items' => $items, 'title' => 'From Test01']);
Let me know if that helped.
- Vaielab
- Member | 5
Hello,
I look to change $this->engine->renderToString to something with
createTemplate.
The closest thing that I manage to make work was
$template = $this->engine->createTemplate('Test01.latte', ['items' => $items, 'title' => 'From Test01']);
$template->render();
I could not found a way to return the template to a string, but anyway, even that way, I still can't manage to get an other error message.
For the variable collector and template path collector, I read the documentation, and I have to be honest, I'm kinda lost.
I'll wait for the next update if you have time to do it, and I'll try
again.
Thank you!
- mystik
- Member | 304
I implemented few fixes that simplified how it can be used and prepared fix of your repo where anylysis works. See https://github.com/…pStan/pull/2 (it requires dev-main version)
To make it work with $this->engine->renderToString
only
TemplateResolver
is needed.
If you want to use custom wrapper for rendering like
TemplateRenderer
we also need custom
TemplateRenderCollector
that would extract parameters from call to
TemplateRenderer::template
. At this point is is quite complex but
it works. We might add easier way to define custom render call
collectors later.
Last edited by mystik (2023-05-05 14:18)
- Vaielab
- Member | 5
Wow, thank you so much both of you!
Everything work perfectly :)
I'll study both of your PR to understand what is happening.
If you wish to improve your doc, you could add an example with phpslim / engine standalone, I'm sure I'm not the only one who wish to have better validation with latte.
Thanks again for all your works, and for the PHPStan plugin!