Handling Content Representations with Router / Specifying Representation with `page()`

Is there a way to use page() and specify which representation you want?

More specifically, if I had a /sitemap page and it has sitemap.txt and sitemap.xml.txt within it, is it possible to specify which representation I want to return in a Kirby Route?

Aside from redirection, it’s unclear to me how I could map something like example.com/foo-bar-sitemap.xml to actually show content from example.com/sitemap.xml. Similar problem for other representations like json api representations.

My naïve approach would be

    [
        'pattern' => 'foo-bar-sitemap.xml',
        'action' => function() {
            $page = page('sitemap.xml');
            return $site()->visit($page);
        }
    ],

but site()->page doesn’t seem to interpret the xml suffix as a content representation.

Even if I used page(sitemap), I’m not sure how I would access the a list of alternative representations.

If all you’re trying to do is create a sitemap, would any of the existing plugins that already do that be able to help?

I’m using sitemap merely as a tangible example.

Kirby has a built-in way to provide your page(s) content using custom representations - there is a section about it in the ‘advanced’ area of the docs.

Does that help?

That’s the mechanism I’m using to actually handle the representation types when accessed from a browser’s standpoint.

What is unclear to me is how I can access those representations from a code standpoint.

Perhaps I want to display a list of alternative representations, or, like in my original example, re-map a URL to show content from some other page’s alternative representation.

You would probably just create them either in your page controller, or page model - e.g., you would create an as_xml() or as_json() method that simply returns the page data you need in the appropriate format.

If there is a template for that representation, you could also load the template in routes (using tpl::load). But that only makes sense if you need that template for other purposes. Other than that, I’d also use methods that return your content in the appropriate format as already suggested by @luxlogica. You can also do things like this:

c::set('routes', array(
  array(
    'pattern' => 'something.json',
    'action'  => function() {
      $p = page('somepage');
      $data = $p->content()->toArray();
      return response::json($data);
    }
  )
));