Translate Custom Route

Hey guys,

Have this custom route setup that is getting a URL from a panel field. I use this tutorial to set up a route that takes in a field from the panel: Routing | Kirby. It needs to be translated, but the current code I am using is not returning the correct translation:

'routes' => [
        [
          'pattern' => 'redirect/(:all)',
          'language' => '*',
          'action'  => function ($language, $uri) {
            if ($page = page($uri) ) {
              go($page->content($language->code())->ref_url());
            }

          }
        ]
      ]

Is this set up incorrectly, or is my syntax incorrect?

Supposing the ‘ref_url’ field is in page ‘mypage’, if you are redirecting the visitor to another page inside the site itself, you could try:

'routes' => [
    [
        'pattern' => 'redirect/(:all)',
        'language' => '*',
        'action'  => function ($language) {
            $lang = $language()->code();
            $pg = page('mypage')->content($lang)->ref_url();
            // assuming we're storing a simple page uri in 'ref_url':
            return site()->visit($pg,$lang);
          }
    ]
]

If you’re storing an external url in ‘ref_url’, you could try something like this:

'routes' => [
    [
        'pattern' => 'redirect/(:all)',
        'language' => '*',
        'action'  => function ($language) {
            $lang = $language()->code();
            $url = page('mypage')->content($lang)->ref_url();
            // assuming we're storing a full external url in 'ref_url':
            go($url);
          }
    ]
]

Does that work?

Thanks for your help :slight_smile:

It is an external URL, so the second approach is the more accurate one. The page has to be dynamic as this is used for many different pages, that is why the URI was being pulled in before.

I tried using this:

    'pattern' => 'redirect/(:all)',
    'language' => '*',
    'action'  => function ($language, $uri) {
      // if ($page = page($uri) ) {
      $page = page($uri);
      $lang = $language()->code();
      $url = $page->content($lang)->ref_url();
      // assuming we're storing a full external url in 'ref_url':
      go($url);
    }
  // }

However, now I am getting this error:

Not too sure why $language is not being able to be read, as I think it is a global variable in Kirby.

I think you’re getting that error because the line should be $language->code(), not $language()->code() - ie., $language is an object, not a function/method (that’s my mistake!). :roll_eyes:

I also suspect that the $page can be magically passed by Kirby to your function, so you might be able to do this:

'action' => function ($language, $page) {
    $lang = $language->code();
    $url = $page->content($lang)->ref_url();
    // assuming we're storing a full external url in 'ref_url':
    go($url);
}

I didn’t notice that either :joy:

I am now getting this error:

When I dump routes, they all look empty (even though they are filled in the panel):
Screen Shot 2021-04-15 at 12.30.06 AM

Ok, what that error is telling us is that the $page variable is a string, not an object.

You can try to see the specific value of $language and $page, by doing a dump() inside the action function, like this:

'action' => function ($language, $page) {
    dump($language);
    ...
}

…then:

'action' => function ($language, $page) {
    dump($page);
    ...
}

In any case, you can always try going back to:

'action' => function ($language, $uri) {
    $page = page($uri);
    $lang = $language->code();
    $url = $page->content($lang)->ref_url();
    // assuming we're storing a full external url in 'ref_url':
    go($url);
}

Thanks for the tip :slight_smile:

I found the source of the problem. This whole setup is to change the URL of some links from full external URLs to something like domain.com/redirect/page-name. The redirect for the page is coming from a page model which adds the redirect path:

<?php class BonusPage extends Page {
      
      public function cloakedUrl() {
          return url('redirect/' . $this->id());
      }
  } ?>

However, in the model, the translation is never passed, so it’s always going to the default one.

Think I may have found a workaround, it seems like the correct translation is not being passed to the config.php router, but if I add the correct translation to the cloakedURL function:

public function cloakedUrl() {
          return url(kirby()->language()->code() . '/redirect/' . $this->id());
      }

It does return the correct translation when I dump the language in the config:

The only issue here is that it is returning two languages, the default one and the correct one.

The documentation for translating page models is quite limited. How can I pass the correct translation into the config.php? Or do you think there would there be a better way to do this?