$site->uri not working in a page controller

Here’s what seems like a fairly simple use of the $site object. I have a page and a corresponding controller, and in the controller I’m trying to get the current URL of the page.


return function($site, $pages, $page) {

  $current_url = $site->uri->path();

  return array(
    'current_url' => $current_url



echo $current_url;
// => PHP Fatal error:  Cannot access protected property Site::$uri`


Ignore the fact that this is kinda circuitous—this is just a stripped down version to try and get at the problem. Shouldn’t I be able to access the $site object from anywhere, even in a controller? Or are the $site, $pages, and $page variables only available to template and snippet files? The documentation for controllers seems to suggest that I should have access to $site.

You cannot even use $site->uri->path() in a template, it will result in the same error, just try something like $site->url() or $site->page()->uri(), which should work.

Oh interesting. So where would one be able to use $site->uri->path() if not in a template? I tried using that in a plugin and it didn’t work, either. The documentation isn’t too clear on where you can use different top level objects like that.

Also, thanks for helping out with the alternative methods!

I can’t find a $site->uri->path() method in the docs or source code?

What do you want to get?

Here are the docs for the URI object. I just need to get the current page’s URL (generated via a route).

  • Using $site->url() just returns the site root, not the full URL
  • Using $site->page()->uri() returns home for some reason, which is weird because I’m not on the home page.

That’s an old blog post, it refers to Kirby 1; have a look at this thread Site URI in Kirby 2.0 not working properly

Thanks for the link, it was helpful. Here’s what I ended up doing to get the current URL:

function get_current_url() {
  $path = kirby()->request()->path();
  $path_string = implode('/', $path->data);
  return site()->url() . '/' . $path_string;

It seems like there would be something baked in Kirby to get the current full URL, but this isn’t too bad.

I still don’t understand why you need to use the site object instead of just calling $page->url()?

$page->url() isn’t returning what I’m seeing in the browser’s address bar; instead I think it’s returning the URL of the page I’m setting in the route:

c::set('routes', array(
    'pattern' => 'episodes/(:all)',
    'action'  => function($all) {
      $data = array(
        'placeholder' => $all
      return array('episode', $data);

Below is the comparison of what I’m getting with $page->url() vs the custom function I made:

$page->url()      => http://dev.tes.com:8888/episode
get_current_url() => http://dev.tes.com:8888/episodes/wonderful-land

I created the route because this part of the site is pulling data from an RSS feed, not from Kirby.