Here I sit on a wet Saturday afternoon trying to solve my problem from earlier this week…
At the moment in my SS4 install VirtualPage
is only displaying actual Product
pages. My client wants to use VirtualPage
to display ProductHolder
page types. Currently all that they get is the page H1 tag, with no content.
According to @Firesphere and @MichalKleiner I need to extend VirtualPage
as VirtualPage
is not inheriting the Controller. There are two ways to do this — I’m trying the method which is ‘less obfuscated’ ie easier for Content Authors to understand.
Except that all I’ve managed to produce from the attached code is a White Screen of Death
Is there anybody out there this Saturday afternoon that can offer advice?
Add public function getControllerName(){ return ProductPageController::class; }
to your VirtualProductPage
That will tell the virtual page to use the ProductPageController as the controller for this virtual page
I didn't mentioned that earlier, because I assumed you got that idea. That was a stupid assumption of me, 🙇
No worries @Firesphere — I’m the one feeling stupid for most of the time!
The amount of times I spent half a day on debugging only to find out I made a typo are countless 😄
Tell me about it! The most frustrating things is, I’m STILL getting to grips with this stuff… front end code is fine but the PHP stuff is unforgiving!
If you think PHP is unforgiving... try Python or Java 😄 (p.s., I ❤️ Python)
OK, managed to rebuild DB, etc and things look good on the backend. However I seem to have really upset the front end — got a very verbose error that starts with:
[Emergency] Uncaught SilverStripe\Core\Injector\InjectorNotFoundException:
EMERGENCY??? Like DANGER, WILL ROBINSON!
Yeps, sounds like you're missing a use
statement?
Damn, now I’m showing my age…
Well, I do actually have a use
statement:
use SilverStripe\CMS\Model\VirtualPage;
Anything else I should be using?
Hmmm?
ReflectionException: Class SilverStripe\CMS\Model\VirtualPage\ProductPageController does not exist in /
Right. Changed the Namespacing to reflect where VirtualProductPage
actually lives. Now I’m simply getting an Infernal Server Error…
<?php namespace App\MyProject; use SilverStripe\CMS\Model\VirtualPage; class VirtualProductPage extends VirtualPage { public function getControllerName() { return ProductPageController::class; } }
I guess that’s progress…
I guess that’s progress…
Anything in the logs?
Set your PHP logging to the most verbose as possible and pray for output?
If you have no control over your php.ini, you can set it in your _config.php
with ini_set()
OK. According to my logs:
[20-Jul-2019 13:26:04 Pacific/Auckland] PHP Fatal error: Class 'SilverStripe\CMS\Model\VirtualPage\VirtualPage' not found in /Users/mikehenden/Sites/Connectors/app/src/VirtualProductPage.php on line 7
also from MySQL:
2019-07-20T02:08:14.007480Z 0 [Note] InnoDB: page_cleaner: 1000ms intended loop took 623048ms. The settings might not be optimal. (flushed=0 and evicted=0, during the time.)
The namespace is SilverStripe\CMS\Model\VirtualPage
You have a \VirtualPage
too much
Ahhh!! Think I’ll just ROTFL for a while…
Spend 4 hours debugging a stupid typo, or rubber duck a bit... Yeaps! Rubber ducking FTW! 😄
Well, NOW I’ve got a Verbose Error — think I had this one before! Starts with:
[Emergency] Uncaught SilverStripe\Core\Injector\InjectorNotFoundException: ReflectionException: Class SilverStripe\CMS\Model\VirtualPage\ProductPageController does not exist in /Users/mikehenden/Sites/Connectors/vendor/silverstripe/framework/src/Core/Injector/InjectionCreator.php:17
ProductPageController does not exist??
It doesn't exist in the namespace provided 😉
Update your use
statements on your VirtualPage extension 🙂
Namespaces are a PITA at first, but when you get used to it, you'll love it 🙂
Had so much trouble with Namespaces! Never had this with SS3! 🤔
so I’m using:
use SilverStripe\CMS\Model\VirtualPage;
looks right to me? 🤔
Yeah, but your ProductPageController isn't in that namespace 😉
so you'll need to add a use statement, that tells PHP to "use" the ProductPageController from your own namespace
OK, thanks! I’ve added:
use App\MyProject\ProductPageController;
which is giving me:
[Emergency] Uncaught SilverStripe\Core\Injector\InjectorNotFoundException: ReflectionException: Class App\MyProject\ProductPageController does not exist in /Users/mikehenden/Sites/Connectors/vendor/silverstripe/framework/src/Core/Injector/InjectionCreator.php:17 Stack trace: #0 /Users/mikehenden/Sites/Connectors/vendor/silverstripe/framework/src/Core/Injector/InjectionCreator.php(17):
Hmmm, that's a loader issue in your composer file
A what??? 😧
PHP error log says:
[20-Jul-2019 14:28:23 Pacific/Auckland] PHP Fatal error: Uncaught PhpParser\Error: Syntax error, unexpected T_USE, expecting ';' or '{' in /Users/mikehenden/Sites/Connectors/app/src/ProductPageController.php on line 5 in /Users/mikehenden/Sites/Connectors/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php:315 Stack trace: #0 /Users/mikehenden/Sites/Connectors/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php(158): PhpParser\ParserAbstract->doParse() #1 /Users/mikehenden/Sites/Connectors/vendor/nikic/php-parser/lib/PhpParser/Parser/Multiple.php(51): PhpParser\ParserAbstract->parse('<?php\n\nnamespac...', Object(SilverStripe\Core\Manifest\ClassManifestErrorHandler)) #2 /Users/mikehenden/Sites/Connectors/vendor/nikic/php-parser/lib/PhpParser/Parser/Multiple.php(32): PhpParser\Parser\Multiple->tryParse(Object(PhpParser\Parser\Php7), Object(SilverStripe\Core\Manifest\ClassManifestErrorHandler), '<?php\n\nnamespac...') #3 /Users/mikehenden/Sites/Connectors/vendor/silverstripe/framework/src/Core/Manifest/ClassManifest.php(500): PhpParser\Parser\Multiple->pars in /Users/mikehenden/Sites/Connectors/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php on line 315
PHP Fatal error: Uncaught PhpParser\Error: Syntax error, unexpected T_USE, expecting ';' or '{' in
You might want to look at that 😄
Cool! No more errors! Unfortunately there’s only the heading… the $Content
area isn’t showing… (which, I think, is where I came in)??
It's progress
It may be, the virtual page doesn't pass down the actual page it's virtualising properly. In the init of the controller, see what the dataRecord is
If it's not a reflection of the page you're trying to virtualise, you might need to do it manually
Thanks again… by “manually” do you mean make a copy of the page that I want to duplicate?
No, inject it. VirtualPage should give you the ID of the page it's trying to duplicate. In your init() on the controller, look for that value and inject said page as being the datarecord instead of what VirtualPage gives you
You say “In the init of the controller, see what the dataRecord is” — unfortunately I have no idea where to look?! Feeling dumb now!
Can you tell me where my ‘init() on the controller’ is please?
URL segment is correct…
Hmmm: <div class="content"></div>
— that’s why it’s empty…
Is this something I need to do on ProductHolderController
— similar to this:
class Page_Controller extends ContentController { public function init() { parent::init(); // do your own stuff here } }
Also, you don't need your VirtualProductPageController class that way 🙂
has anyone found a linting tool that will work on SilverStripe templates (i.e. lint the HTML but not throw a fit when it finds template related tags)?
@guttmann there's a syntax highlighter for SS templates for VS Code (and PHPStorm too, i think)
ah yep - I do use the PhpStorm extension but I was hoping there was some form of linter that I could use to catch issues in our CI system (not everyone in the team using the same editors/IDEs)