How to use custom route with controller and template?

I want to define a custom route for https://mydomain.de/channel/CHANNEL_ID. The page should then show some data for this channel.

I created a route in config.php like this:

// channel page route
c::set('routes', array(
  array(
    'pattern' => array('channel/(:any)'),
    'action'  => function($channelId) {
      $data = $channelId;
      return array('channel', $data);
   }
  )
));

I created a template called channel.php in the templates folder. I created a channel.php in the controllers folder.

I need to pass the CHANNEL_ID in the url to the controller to process some data there. This is what my controller code looks like right now:

return function($site, $pages, $page, $args) {
	// get channel id from url path
	$channelId = $args;

	// DO SOME STUFF TO FETCH CHANNEL DATA
    $channel = 'bar';

	// return vars to use in template
	return [
		'channel' => $channel
	];

};

Then I want to use the data generated there in my channel.php template. Accessing it through the template variable $channel.

However it currently does not work the way I am doing it. I guess there is something wrong with my route configuration? Can someone help?

  1. $data in your route must be an array
  2. You are not passing the $channelIdvariable down to the template, only your $channel

I fixed the routing function to pass an array to the controller:

c::set('routes', array(
  array(
    'pattern' => array('channel/(:any)'),
    'action'  => function($channelId) {

      $data = array(
        'channelId' => $channelId
      );

      return array('channel', $data);
   }
  )
));

This is currently intended just for simplicity to test if everything works together correctly. Will be replaced in the future.

I now receive this error when I access /channel/foobar:

Argument 1 passed to Kirby::render() must be an instance of Page, boolean given, called in /var/www/virtual/i42n/html/kirby/website/kirby/kirby/component/response.php on line 27

I think the problem is that kirby does not know that you are visting the channel template here.

Try this:

c::set('routes', array(
  array(
    'pattern' => array('channel/(:any)'),
    'action'  => function($channelId) {

      $data = array(
      'channelId' => $channelId
      );

      return array(
        site()->visit('channel'),
        $data,
      );
    }
  )
));

Edit: Ok actually your code should work also

Does a page called channel actually exist?

That was the issue. I created the page and now it works. Thank you guys for your help!