Virtual Pages and hooks

Me again, about virtual pages, again :wink:

Since virtual pages aren’t “physical” page, are they (in a matter of hooks) created everytime or they’re update one they’re created ?

We are building a restaurant website whose menu is based on a delivery API (instead of force the client to enter his menu on both platform). I want to fetch all the available datas (this part is done and work properly) and upload the image on the kirby ecosystem - but for that, I need a hook or something else to trigger my upload/assign method.

I did some tests with page.update:after and page.create:after but can’t get any signals that the page has been updated or created.

Is the best is about doing all this stuff in my model before Pages::factory ?

For the purpose, here’s a part of my model: ($cover is the valid image url from the other platform)


class MenuCategoryPage extends Page
    public function children()
		// I hide sensible information before this part, but let's say that $response is a valid API response
		$response = Remote::request($url, $options);

		if ($response->code() === 200) {
			$content = $response->content;
			$results = json_decode($content)->data->items;

		foreach ($results as $key => $item) {
			// Transformers
			$cover = Str::replace($item->image, '/resize/300/', '/');
			// Set the page object
			$pages[] = [
				'slug'	 => Str::slug($item->name),
				'num'	  => $key+1,
				'template' => 'menu_item',
				'model'	=> 'menu_item',
				'content'  => [
					'ueat_id' => $item->id,
					'title'	=> $item->name,
					'description'	=> $item->description,
					'cover'	=> $cover,
					'regular_price' => $item->regularPrice,
					'display_price' => $item->unitPrice,
		return Pages::factory($pages, $this);

Unless you cache your results (which you should do for performance), a new request to the API is made every time you load the page.

As regards the images, check out this example: Virtual Files for page?

I bet its trigger on every request, my point was more about : Is virtual pages trigger Kirby hooks (:update or :create) - guess not.

As for the files, I don’t wanna use “Virtual Files”, I wan’t to upload them on the site to not use the platform resources everytime I need them.

I found the createFile() method and try to make it work.

// Handle cover image (000-a-item-name.jpg)
$image_filename = "{$ueat_id}-{$slug}.jpg";
$images_directory = site()->find('ressources/images');
$file = File::create([
	'source' => $cover,
	'parent' => $images_directory,
	'template' => 'image',
	'filename' => $image_filename

Returns “The file could not be created”

// /kirby/src/Cms/FileActions.php
// overwrite the original
if (F::copy($upload->root(), $file->root(), true) !== true) {
    throw new LogicException('The file could not be created');

$cover is a valid image, verified by a file_get_contents() call

No, unless you update or create pages from Kirby’s Panel (using a Page model to send data to the API).