Pass data from Router to Page Model

I have a route like this:

array(
    'pattern' => 'book/(:any)',
    'action'  => function($id) {
      $response = json_decode(Request::get(API . 'books/' . $id)->send());
      if(!$response->data) {
      	//must be an error - send 404
      	return site()->errorPage();
      }

      site()->visit('book', myLanguageFunction());
      return array('book', ['book' => $response->data]);
    }
  )

Request::get fetches data from an API.
Now I would like to let my Page Model (BookPage) know about this $book variable without having to pass it through the template. Is there a “Kirby Way” or do I have to go through globals?

What you could do is to manually create an instance of the BookPage class and return that:

return new BookPage(site(), 'book', $response->data);

Your model would then need a constructor that stores the third param in an instance method.

I have not tested this though and don’t know how reliable this is.

I can’t override the Page constructor because Kirby wants to instantiate the page no matter what.

function($id) {
      $response = json_decode(Request::get(API . 'books/' . $id)->send());
      if(!$response->data) {
      	//must be an error - send 404
      	return site()->errorPage();
      }

      return new BookPage(site(), 'book', $response->data);
}

results in

 Warning: Missing argument 3 for BookPage::__construct(), called in /var/www/html/kirby/core/page.php on line 375

Even

  site()->visit('book');
  site()->page()->setBook($response->book);
  return array('book', []);

doesn’t seem to work, since site()->page() isn’t the same instance as the one that finally renders the template.

Ah, OK.

The warning could be fixed by making the third param optional, but if the instance doesn’t get used, this doesn’t make sense.