Simple multi-language virtual page doesn't work in API call

I start moving some ‘theme’ concepts to a plugin. I need a ‘protected’ page to attatched all my children and grand-children, the ‘Simple virtual page’ seems to be a good start for that.

Using the last example of this guide and the routes extension I try to build my static ‘root’ page and yet, it doesn’t work as expected.

“Physical access” (my-site.local/fr/ueat and my-site.local/en/ueat) are working, but API access attempt return 404s (other non-virtual pages are ok).

Am I missing something (Yes, I need it to be multi-language) ?


Kirby::plugin('mambomambo/ueat', [
	'options' => [
		'api' => 'https://api-beta.ueat.io/graphql',
		'method'	=> 'POST',
		'cache' => true,
		'expires' => (60*60), // 1 hour,
		'apikey' => null,
		'culture' => null,
		'data'	=> "{'query': '{&QUERY%}'}",
		'params' => [],
	],
	'routes' => [
		[
			'pattern' => '(?:(:any)//?)?ueat',
			'language' => '*',
			'action'  => function ($lang) {
				$data = [
					'slug' => 'ueat',
					'template' => 'ueat_menu',
					'model' => 'ueat_menu',
					'translations' => [
						'fr' => [
							'code' => 'fr',
							'content' => [
								'title' => 'Menu (FR)',
							]
						],
						'en' => [
							'code' => 'en',
							'content' => [
								'title' => 'Menu (EN)',
							]
						]
					],
				];

				$page = Page::factory($data);

				site()->visit($page, $lang);

				return $page;
		  }
		]
	],
	'pageModels' => [
		'ueat_menu'		=> 'UeatMenuModel',
		'ueat_category' => 'UeatCategoryModel'
	]
]);

I’m not sure if a virtual page works as a parent for virtual pages. I did a quick test with the example from the docs and got the children to display on the virtual parent page but the children links didn’t work. I will test again with a fresh kit.

Have you adapted your model with the children method to support multiple languages??

The issue, for the moment isnt really the children, the virtual page work well if I type .com/fr/ueat - but not through an API call… I got a 404.

I test it alone, without children or so, a simple virtual page from the Kirby Guides, and it doesnt work.

Content of my plugin/index.php:

Kirby::plugin('mambomambo/ueat', [
	'routes' => [
		[
			'pattern' => '(?:(:any)//?)?ueat',
			'language' => '*',
			'action'  => function ($lang) {
				$data = [
					'slug' => 'ueat',
					'template' => 'ueat_menu',
					'model' => 'ueat_menu',
					'translations' => [
						'fr' => [
							'code' => 'fr',
							'content' => [
								'title' => 'Menu (FR)',
							]
						],
						'en' => [
							'code' => 'en',
							'content' => [
								'title' => 'Menu (EN)',
							]
						]
					],
				];

				$page = Page::factory($data);

				site()->visit($page, $lang);

				return $page;
		  }
		]
	]
]);

Content of my template/ueat_menu.php:

<?php dump( page() ) ?>

Content of my test api temlate:

<html>
  <head>
    <title>API Example</title>
  </head>

  <body>
    <script>
      const csrf = "<?= csrf() ?>";

      fetch("/api/pages/ueat", {
          method: "GET",
          headers: {
            "X-CSRF" : csrf
          }
        })
        .then(response => response.json())
        .then(response => {
          const page = response.data;
          // do something with the page data
          console.log(page);
        })
        .catch(error => {
          // something went wrong
        });
    </script>
  </body>
</html>

And then create a content page with test as the template, I create /content/5_test/test.fr.txt.

  1. /fr/ueat output me the page object as a charm
  2. /fr/test throw me a 404 in the console, where my issue is: a virtual page doesn’t show up in the API.

I assume that such virtual pages created via a route are not accessible via the API. They do not show up in the Panel, either.

I think this would only work if we had a site model that would allow us to create virtual pages as children of the site object.

Guess I will try to make a more API approach, make my categories and items available through a siteMethod to be used wherever wanted. This will fill our immediate needs since the first website with this plugin run with Vue.js.

Thank you!

Why don’t you create this ueat page in the file system?

Because I want it to be plug-and-play without any physical dependencies; the idea with the ueat virtual page was to make the slug overridable through a plugin option setting.

You could also create a custom API endpoint for the page: https://getkirby.com/docs/reference/plugins/extensions/api

I’m just not sure how to return the response in the same format as api/pages/somepage

<?php 
Kirby::plugin('mambomambo/ueat', [
    'api' => [
        'routes' => [
            [
                'pattern' => 'custom/ueat',
                'action'  => function () {
                    $data = [
                        'slug' => 'ueat',
                        'template' => 'ueat',
                        'model' => 'ueat',
                        'translations' => [
                            'fr' => [
                                'code' => 'fr',
                                'content' => [
                                    'title' => 'Menu (FR)',
                                ]
                            ],
                            'en' => [
                                'code' => 'en',
                                'content' => [
                                    'title' => 'Menu (EN)',
                                ]
                            ]
                        ],
                    ];
                    $page = Page::factory($data);
                    return $page->toArray();
              }
            ]
        ]
    ]
	
]);
 fetch("/api/custom/ueat", {