Get page object for modular page from PHP

I’m working on a plugin that dynamically adds some form inputs and form data to existing forms. These forms could also be on modular pages. I need to read the header data (frontmatter) of the pages that include the relevant form (or forms). Doing it this way works if the form is included in a regular page:

public function onFormInitialized(Event $event) {
    $page = $this->grav['page'];
    $header = $page->header();
    /* ... */

However, if the form is included in a modular page, then the first line, $this->grav['page'] will cause the entire page to display a 404.

What’s the right way to achieve this that will work for any type of page?

I tried to get the page from the form itself:

public function onFormInitialized(Event $event) {
    $form = $event['form'];
    $page = $form->getPage();
    /* ... */

But this leads to:

Return value of Grav\Plugin\Form\Form::getPage() must implement interface Grav\Common\Page\Interfaces\PageInterface, null returned

So the search continues…

@domsson, Bit of playing with the debugger…

Let say we have a modular with a form as child module:

├── 01.home
├── ...
└── 04.modularform
    ├── _contact
    │   └──

Then in our plugin we can do the following to get the header from both the modular and its child form module.

public function onFormInitialized($event)
    /** @var Form */
    $form = $event['form'];

    /** @var Page */
    $modular = $form->getPage();
    $modularHeader = $modular->header();

    /** @var Collection */
    $collection = $modular->collection();

    /** @var Page */
    $contact = $collection->filter(fn ($module) => $module['slug'] === '_contact')->first();
    $contactHeader = $contact->header();


Update 2021-04-12:
On revisit of this code in a newer post, it seems that my suggested code does indeed not work in all circumstances. It only works when the page has already been cached. If not yet cached, the page is not yet available during onFormInitialized.

1 Like

I’m impressed by your knowledge of Grav and your dedication to help, pamtbaau. Thank you very much. Using the $form->getPage() approach is exactly what I tried today, but having the line in there would lead to an error, as outlined in my reply above. I take it you tried your code, however, and it worked for you?